Skip to content

REST API Skill

HTTP REST endpoints, web action routines, authentication, and request/response processing.

Invoke with: /rest

Key APIs

c
/* Action registration */
void webAddAction(WebHost *host, cchar *prefix, WebProc fn, cchar *role);

/* Request reading */
ssize webRead(Web *web, char *buf, size_t bufsize);
int webReadBody(Web *web);
cchar *webGetVar(Web *web, cchar *name, cchar *defaultValue);
cchar *webGetHeader(Web *web, cchar *key);

/* Response writing */
ssize webWrite(Web *web, cvoid *buf, size_t bufsize);
ssize webWriteFmt(Web *web, cchar *fmt, ...);
ssize webWriteJson(Web *web, const Json *json);
ssize webWriteResponse(Web *web, int status, cchar *fmt, ...);
int webError(Web *web, int status, cchar *fmt, ...);
void webRedirect(Web *web, int status, cchar *url);

Action Handler Pattern

c
static void testAction(Web *web)
{
    webWriteFmt(web, "Hello World, now is: %s\n", rFormatLocalTime(0, 0));
    webFinalize(web);
}

/* Registration in ioStart(): */
webAddAction(ioto->webHost, "/test", testAction, 0);

JSON API Endpoint

c
static void statusAction(Web *web)
{
    Json *response = jsonAlloc(0);
    jsonSet(response, "status", "ok");
    jsonSetNum(response, "uptime", rGetUptime());
    webWriteJson(web, response);
    jsonFree(response);
}

webAddAction(ioto->webHost, "/api/status", statusAction, 0);

Accepting JSON POST Data

c
static void updateAction(Web *web)
{
    Json *body;

    webReadBody(web);
    body = jsonParse(web->body, 0);
    cchar *name = jsonGet(body, "name");

    Json *response = jsonAlloc(0);
    jsonSet(response, "status", "updated");
    webWriteJson(web, response);
    jsonFree(response);
    jsonFree(body);
}

Authentication

c
PUBLIC int ioStart(void)
{
    webAddAction(ioto->webHost, "/auth/login", login, 0);
    webAddAction(ioto->webHost, "/auth/logout", logout, 0);
    return 0;
}

static void login(Web *web)
{
    cchar *username = webGetVar(web, "username", 0);
    cchar *password = webGetVar(web, "password", 0);
    if (smatch(password, "demo")) {
        webLogin(web, username, password);
        webRedirect(web, 302, "/welcome.html");
    } else {
        webRedirect(web, 401, "/");
    }
}

Web Server Configuration

json5
{
    web: {
        endpoints: [{ address: ':4000' }],
        routes: [
            { match: '/api/', handler: 'action' },
            { match: '/',     handler: 'file', documents: './site' }
        ],
        sessions: { cookie: '-ioto-session-', lifespan: '30mins' },
    }
}

Important Notes

  • Action handlers run in fibers — I/O calls yield cooperatively.
  • Use webFinalize(web) to signal response is complete.
  • webGetVar() returns query params and POST form fields.
  • Role-based auth: pass role name as 4th arg to webAddAction().
  • Use ioto->webHost when running inside the Ioto agent.