B4J Tutorial Pakai framework v4

Part #1: Get Started

Introduction

This tutorial is based on [Project Template] Pakai Server v4.

Installation
  1. Download and put the following files to Additional Libraries folder
    B4J:
    - Pakai Server (4.00).b4xtemplate
    - WebApiUtils.b4xlib
    (v4.70)
    B4X:
    - MiniORMUtils.b4xlib (v3.30)
  2. If you want to use MySQL database, ensure you also have MySQL jdbc driver inside your B4J Additional Libraries folder.
    e.g mysql-connector-java-5.1.49
Create Project
  1. Once all the required libraries and template are in place, you can start B4J IDE.
  2. Select from File menu, New, Pakai Server (4.xx)
    1
  3. Enter the name of your project as you like. Then click OK.
    1752468079951.png
  4. Now the project is ready to run as it is.
Running the Project
  1. Click menu Project, Compile & Run (F5) or the play button on the toolbar.
  2. Hover you mouse pointer to the AppStart sub and click on the highlighted link to open the app on your web browser.
    3
  3. The browser will open and load the index page.
    It is a CRUD web application where you can add a new product (Create), search for a product (Read), edit an existing product (Update) and delete a product (Delete).
  4. It has already generated some common APIs following the RESTful API principal.
    To see the list of APIs, click the API link with a gear icon on top navigation bar.
    4
  5. You will be redirected to the API documentation page.
    You will see there are endpoints such as GET, POST, PUT and DELETE which are represented in different colours.
    5
  6. You can click on any item to expand the section.
Perform Tests

GET
  1. Click on the first end point name GET Read all Categories
  2. Click on the green Submit button.
  3. The form will send an AJAX request to the API server and return a JSON response (Code 200 for Success).
    6
POST
  1. To test a POST end point, click the third item with labeled POST /api/categories.
  2. Edit the content inside the Body text area, i.e value of the category_name in the illustration and click the purple Submit button.
    1752469972742.png
 
Last edited:

aeric

Expert
Licensed User
Longtime User
Part #2: Configure Settings
  1. A config.ini is created when you compile the project for the first time in Debug (or Release) mode.
  2. You can open the file using Notepad or any Text Editor.
  3. After you made any changes, you need to compile the project again for the settings to take effect.
B4X:
# Define App Constants
HOME_TITLE=PAKAI FRAMEWORK
APP_TITLE=Pakai
APP_TRADEMARK=PAKAI
APP_COPYRIGHT=Copyright Computerise System Solutions 2025
  1. You can edit these settings.
  2. It will applies to the text displayed on the front-end and API documentation page.
  3. Similar to config.properties, the values does not support UTF8. You may want to set text for non-English characters in the code.
B4X:
# Server Path
ROOT_URL=http://127.0.0.1
ROOT_PATH=
API_NAME=api
API_VERSIONING=False
  1. ROOT_URL (default=http://127.0.0.1) is for setting the server URL. You can edit to your domain name in production release.
  2. ROOT_PATH (default=<empty>) can be set to other name e.g /web
  3. API_NAME (default=api) is better to leave as default.
  4. If you changed it, you need to use conf.ApiName in the code. You also need to edit html templates and JavaScript files.
  5. API_VERSIONING (default=False) can be set to e.g /v1 or /preprod
B4X:
# Java server port
ServerPort=8080
SSLPort=0
  1. It is important to set the correct number for B4J server port.
  2. Make sure the port number is not used by another service or blocked by the firewall.
  3. You can set the port to 80 if you want
  4. It is recommended to use SSL protocol in production. If SSLPort number is set to 0, SSL is disabled.
  5. You can set the value to non-zero to enable it e.g 443
B4X:
# SSL Keystores
# Generate a keystore from Windows CMD
# C:\Java\jdk-11.0.1\bin\keytool -keystore keystore -alias jetty -genkey -keyalg RSA
# Copy keystore file to Objects folder of the B4J project
SSL_KEYSTORE_DIR=/etc/letsencrypt/live/mydomain.com
SSL_KEYSTORE_FILE=keystore
SSL_KEYSTORE_PASSWORD=xxxxxxxxx
  1. If SSLPort is enabled, you need to set the keystore settings.
  2. During development, you can use CMD to call keytool in the JDK to generate a self sign keystore file.
  3. Put this file in Objects folder and leave the SSL_KEYSTORE_DIR setting as <empty>.
  4. During production, you can use a real certificate or generate one using LetsEncrypt.
B4X:
# DATABASE CONFIGURATION

## SQLite configuration:
DbType=SQLite
DbFile=pakai.db
DbDir=
  1. Default DbType is set to SQLite.
  2. You can change the DbFile as you like e.g car.sqlite
  3. You can leave DbDir as <empty> to store the file inside Objects directory.
  4. If you want to save the file in a different location, you need to set it using forward slash or escape character e.g C:/server/db or C:\\server\\db
  5. If you want to use MySQL as backend database, uncomment the settings like the following example.
    B4X:
    ## MySQL configuration:
    DbType=MySQL
    DbName=car
    DbHost=localhost
    DbPort=
    DriverClass=com.mysql.cj.jdbc.Driver
    JdbcUrl=jdbc:mysql://{DbHost}:{DbPort}/{DbName}?characterEncoding=utf8&useSSL=false
    User=root
    Password=password
    MaxPoolSize=0
  6. You can leave DbPort as <empty> if MySQL is running on default port 3306.
  7. You can edit the DbName, User, Password, MaxPoolSize or other settings according to your needs.

Always start a new question with the name Pakai if you have any question on this tutorial.
 

aeric

Expert
Licensed User
Longtime User
Part #3: How Does the Project Work?

Production

  1. This is a non-UI or console app. It doesn't have native UI library or component. You can't add any B4J library that depends on XUI or jFX.
  2. After the project is compiled as Release, you can execute the binary file using CMD (Windows) or Terminal (Linux).
  3. To host the server app, it is recommended to find a VPS that you have full access to call the binary using a remote SSH terminal.
  4. You also need to have a JDK installed on the server for you to call the .jar file.
  5. It is recommended that you put the compiled binary file e.g server.jar, together with the www directory inside a location that user has write permission.
  6. This is to ensure the server can write to the database file if you are using SQLite to keep inside the location same as the binary file.
  7. You also need to ensure the server can read the config.ini file, asset files in www directory and write some access logs.
Development
  1. The server starts to call the AppStart sub
  2. The first line inside this sub is InitServer
  3. This sub will create a default config.ini file
  4. The default settings will then loaded as the server configuration
Configurable
B4X:
Private Sub Configurable
    #If DEBUG
    conf.EnableHelp = True
    #End If
    #If RELEASE
    conf.EnableSSL = True
    #End If
    conf.EnableCORS = True
    conf.VerboseMode = True
    conf.StaticFilesBrowsable = False
End Sub
  1. You can just leave the default code as it is
  2. As you can see, we want to enable the Help during Debug or development with the code conf.EnableHelp set to True
  3. In Release or production, we would want to enable SSL to let the server run using https protocol
  4. EnableCORS setting is optional if we serve the frontend under the same backend server
  5. VerboseMode is new in Pakai framework to replace SimpleResponse in v3. It is use for formatting the JSON/XML response.
  6. StaticFilesBrowsable is set to False to restrict the client to list the contents of your www assets directory from the browser.
ConfigurePort, ConfigureCORS, ConfigureStaticFiles are subs to handle the inner works. You don't need to understand how they work.
CreateJSFiles sub is just for generating the Javascript files on runtime based on configured settings. It is not recommended to modify it if you are not sure.

InitDatabase
  1. Pakai uses MiniORMUtils library to create a dummy database for you to get started.
  2. Please post a new question if you want to learn more about using this library in Pakai framework.
  3. If you want to switch from SQLite to MySQL, select MySQL from the Build Configurations dropdown list.
  4. Make sure you have commented the SQLite configuration in config.ini and enable the MySQL section.
  5. If the configuration does not match, it will show an error message and the application will be terminated immediately.
  6. There are 3 subs added at the bottom of Main module to simplify the code when using MiniORMUtils.
    B4X:
    Public Sub DBType As String
        Return conn.DBType
    End Sub
    
    Public Sub DBOpen As SQL
        Return conn.DBOpen
    End Sub
    
    Public Sub DBClose
        conn.DBClose
    End Sub

Always start a new question with the name Pakai if you have any question on this tutorial.
 

aeric

Expert
Licensed User
Longtime User
Part #4: Server Handlers

Conventions

  1. When working with Pakai Server template, the following naming convention are recommended to differentiate the purpose of the handler class.
    • Api Handler - to read the Request from the URI contains the path /api and output the Response as JSON/XML
    • Web Handler - to read the Request from the URI without the /api path and output the Response as HTML
  2. For e.g there are 2 handlers for Categories i.e CategoriesApiHandler and CategoriesWebHandler.
    Categories handlers
  3. As you can guess, CategoriesApiHandler is use for taking care of the API endpoints for Categories while CategoriesWebHandler is use to display the web page to manage the Categories.
  4. IndexWebHandler is use to display the index page when a user browse to the root path.
  5. The index page calls the API endpoints from ProductsApiHandler and FindApiHandler.
  6. HelpHandler is use to display the API documentation page. It will be use to call any API endpoint that you have created.
  7. Each Web handler is linked to its respective JavaScript file to make AJAX calls and process the returned JSON Response from an Api handler.
Adding Server Handler
  1. There are 2 ways to add a Server Handler.
  2. We can click on the menu Project, Add New Module, Class Module,
    Click on the menu Project
  3. However, I recommend another way. Right click on the Handlers group in Modules tab and select Server Handler.
    By this way, we don't need to drag the class into the group later.
    Right click on Modules group
  4. Enter the name of the handler and click OK. It is recommended to use name associated with the model/route. e.g /api/users -> UsersApiHandler
  5. Enter the name of the handler
  6. An empty class with a Handle sub is generated.
    B4X:
    'Handler class
    Sub Class_Globals
    
    End Sub
    
    Public Sub Initialize
    
    End Sub
    
    Sub Handle(req As ServletRequest, resp As ServletResponse)
    
    End Sub
  7. Remember to add the new handler in Main module before calling srvr.Start.
  8. Example:
    B4X:
    srvr.AddHandler($"/${conf.ApiName}/users/*"$, "UsersApiHandler", False)
  9. Please continue to read tutorial Part #5 on how to use Code Snippets to add boilerplate code for the handler.

Always start a new question with the name Pakai if you have any question on this tutorial.
 
Last edited:

aeric

Expert
Licensed User
Longtime User
Part #5: Using Code Snippets
  1. We have learned in Part #4 that we need to write our code inside Server Handlers.
  2. We can save time by generating some boilerplate code using Code Snippets included inside WebApiUtils.
  3. We continue to work with UsersApiHandler.
  4. Let's delete all the code but left the Class_Globals sub.
    1752475120529.png
    Note: We can also use a Standard class.
  5. Put your cursor inside Class_Globals sub, now start typing "globals".
    1752475160040.png
    Select the "Api Class Globals" Code Snippet using the Up/Down key and press Enter.
  6. The result is the following:
    B4X:
    Sub Class_Globals
            Private Request As ServletRequest
            Private Response As ServletResponse
            Private HRM As HttpResponseMessage
            Private DB As MiniORM
            Private Method As String
            Private Elements() As String
            Private ElementId As Int
    End Sub
  7. The variable names are quite self explanatory. We will be using HttpResponseMessage from WebApiUtils and MiniORM class.
  8. Put the cursor after the Class_Globals sub and start typing "handler".
    Use the Up/Down key to select "Api Handler" code snippet then press Enter.
    1752475191851.png
  9. The default code is added. You will notice there are some texts are highlighted.
    1752475222524.png
  10. Replace "EndPoints" with "Users" for plural word and "EndPoint" with "User" for singular word.
    1752475247554.png
  11. Press Tab key to switch to next occurrences if they exist.
    Here, we also need to change the "TableName" to the name of your users table.
    1752475268394.png
  12. When the cursor returned to the first highlighted text, we can press Enter to accept the changes.
  13. Now the handler is ready. You can make further customization to this handler.
  14. Take note that we still need to create the users table and add the handler to the server.
    Main:
        srvr.AddHandler("/categories/*", "CategoriesWebHandler", False)                     ' Web handler
        srvr.AddHandler($"/${conf.ApiName}/categories/*"$, "CategoriesApiHandler", False)   ' API handler
        srvr.AddHandler($"/${conf.ApiName}/products/*"$, "ProductsApiHandler", False)       ' API handler
        srvr.AddHandler($"/${conf.ApiName}/users/*"$, "UsersApiHandler", False)             ' API handler
  15. To add the endpoints to API documentation, add the handler to Initialize sub in HelpHandler.
    HelpHandler:
    Public Sub Initialize
        AllMethods.Initialize
        AllGroups.Initialize
        Handlers.Initialize
        Handlers.Add("CategoriesApiHandler")
        Handlers.Add("ProductsApiHandler")
        Handlers.Add("FindApiHandler")
        Handlers.Add("UsersApiHandler")
    End Sub
  16. You can use BuildMethods sub to build the endpoint section.

Always start a new question with the name Pakai if you have any question on this tutorial.
 
Top