ExpressLite Extension v1

ExpressLite Extension V1

ExpressLite is a non-visible extension that brings a lightweight HTTP server to Android, with an Express.js-like workflow: register routes (GET/POST/PUT/DELETE/ALL), capture path params (/hello/:name), read query, headers, and body (text/JSON), enable CORS, and send responses from Blocks.

Why for Kodular/AI2?

  • No external libraries (pure ServerSocket) β†’ compiles on Kodular/AI2 without JARs.
  • Java 7 compatible (no lambdas/Streams).
  • Great for LAN/edge debugging, local webhooks, device-to-device APIs.

:sparkles: Features

  • Express-style route patterns: /path/:param and wildcard *
  • Events: OnRouteRequest and OnNotFound
  • Respond with Text / JSON / Binary (Base64)
  • CORS with preflight OPTIONS
  • Properties: Port, LocalURL(), RequestTimeoutMs
  • Zero external dependencies

:puzzle_piece: Installation

  1. Import ExpressLite.aix into your Kodular/AI2 project.
  2. Drag the ExpressLite non-visible component to the screen.
  3. Ensure the app has INTERNET permission (enabled by default).

:rocket: Quick Start

Blocks outline:

  1. Set Port = 8080

  2. Call StartServer() β†’ read LocalURL() (e.g. http://192.168.1.5:8080)

  3. Register routes:

    • AddRoute("hello", "GET", "/hello/:name")
    • AddRoute("echo", "POST", "/echo")
  4. Handle OnRouteRequest β†’ reply using SendTextResponse / SendJsonResponse.

Test from PC (replace IP with LocalURL()):

# GET + path param & query
curl "http://192.168.1.5:8080/hello/Rasi?lang=id"

# POST JSON
curl -X POST "http://192.168.1.5:8080/echo" \
  -H "Content-Type: application/json" \
  -d '{"msg":"Hello world"}'

:test_tube: Simplest Example: return "hello" at "/"

Blocks (pseudo):

when Screen.Initialize
  set ExpressLite.Port to 8080
  call ExpressLite.StartServer
  call ExpressLite.AddRoute("root", "ALL", "/")

when ExpressLite.OnRouteRequest(routeName, requestId, method, path, paramsJson, queryJson, headersJson, bodyText)
  if routeName = "root"
    call ExpressLite.SendTextResponse(requestId, 200, "text/plain; charset=utf-8", "hello")

Test:

curl "http://<PHONE-IP>:8080/"
# -> hello

:books: API Reference

Properties

Name Type Description
Port Number Server port. Set before StartServer().
LogEnabled Boolean Enable/disable internal logs (optional).
RequestTimeoutMs Number Time limit to wait for a Block response (default 30000 ms).
LocalURL() Text Current base URL (e.g., http://192.168.1.5:8080).

Functions

Function Parameters Description
StartServer() β€” Starts the server. Returns base URL (Text).
StopServer() β€” Stops the server if running.
SetCORS(enabled, allowOrigin, allowMethods, allowHeaders) Boolean, Text, Text, Text Enable/configure CORS. Default: enabled with * and OPTIONS preflight.
AddRoute(routeName, method, pathPattern) Text, Text, Text Add a route. method: GET/POST/PUT/DELETE/ALL. pathPattern supports :param & *. Returns effective routeName.
RemoveRoute(routeName) Text Remove a route by name.
ClearRoutes() β€” Remove all routes.
SendTextResponse(requestId, status, contentType, body) Text, Number, Text, Text Send a text response.
SendJsonResponse(requestId, status, jsonText) Text, Number, Text Send a JSON response (Content-Type: application/json; charset=utf-8).
SendBinaryResponse(requestId, status, mimeType, base64Data) Text, Number, Text, Text Send a binary response from Base64.

Events

Event Parameters Description
OnRouteRequest routeName, requestId, method, path, paramsJson, queryJson, headersJson, bodyText Fired when a route matches. Use requestId with a Send...Response function to reply.
OnNotFound requestId, method, path Fired when no route matches (404). You may reply manually: SendTextResponse(requestId, 404, "text/plain", "Not Found").

Notes about event params

  • paramsJson β†’ extracted from :param in pathPattern (e.g., /user/:id β†’ {"id":"42"}).
  • queryJson β†’ query map with array values per key (supports ?x=1&x=2).
  • headersJson β†’ headers map (single value per key).
  • bodyText β†’ request body as string (client must send Content-Length; chunked is not supported).

:compass: Route Pattern Examples

Pattern Matches paramsJson
/hello/:name /hello/Ana {"name":"Ana"}
/file/* /file/a/b/c.txt {} (use full path if needed)
/u/:id/profile /u/42/profile {"id":"42"}

:locked_with_key: Security & CORS

Enable CORS if you call the server from a web page:

SetCORS(true, "*", "GET,POST,PUT,DELETE,OPTIONS", "Content-Type, Authorization")

For private LAN tools, * is convenient. For stricter setups, whitelist origins and headers.


:hammer_and_wrench: Troubleshooting

  • Cannot access from PC
    Ensure phone and PC are on the same Wi-Fi/LAN. Check firewall/router/VPN.

  • 504 Timeout
    OnRouteRequest fired, but no Send...Response was called within RequestTimeoutMs. Ensure you respond.

  • Empty body
    Server reads body via Content-Length (no chunked support). Make sure clients send the header and proper length.

  • Internet/WAN exposure
    Not recommended. This is a lightweight LAN server. If you must, put a reverse proxy/TLS in front and implement authentication.


:warning: Limitations

  • No built-in TLS (HTTPS).
  • No keep-alive / chunked transfer (one request per connection β†’ simple and stable).
  • Large uploads/multipart not optimized yet.
  • Not intended for high traffic or public Internet exposure.

Download

com.rasitech.expresslite.aix (31.6 KB)


:new_button: Changelog

  • v2 β€” Self-contained server (ServerSocket), CORS preflight, JSON helpers, this EN doc.
  • v1 β€” Initial NanoHTTPD-based prototype (replaced to remove external dependencies).

:page_facing_up: License

Sample code & docs: Apache-2.0. Feel free to use and modify with reasonable attribution.


:person_raising_hand: FAQ

Q: Can I use it as a local webhook endpoint?
A: Yes. Run the server on the phone, keep clients on the same LAN, or use a tunnel on a separate machine (mind the security).

Q: Can it serve static files?
A: Current focus is replying from Blocks (Text/JSON/Binary). Static files can be added in a future version if there’s interest.

Q: WebSocket support?
A: Not yet. The scope is a simple HTTP request/response server. If the community needs it, it can be explored.

5 Likes