Skip to main content

App Backend

The backend is a Node app under app-backend/. You implement business logic; the Appnest stack loads server.js, wires routing, and exposes your exports to the platform.


Entry point: app-backend/server.js​

  • Only functions exported from server.js can be invoked by the platform (backend API calls, event handlers, scheduled work—per your manifest.json).
  • Register API surfaces under backend_api_functions and event handlers under event_listener_functions (each handler must match an export name). Full schema: Manifest.

AppnestFunctions for backend code​

NeedModuleDoc
Outbound HTTP$fetchExternal API
Key/value storage$dbData Storage
Files (signed URLs, list, delete, …)$fileFile Storage
Scheduling$scheduleSchedule
Call another backend function$nextBackground Job

How to code​

  • Use CommonJS only: require / module.exports. Do not use import / export / import() in app-backend (the validate command enforces this).
  • Keep export names identical to keys in manifest.json so validation passes.
  • Function signature: Each backend handler is invoked with a single argument object; destructure payload from it—({ payload }). Return a plain object, or new ResultData({ body, statusCode }) when you want to set HTTP-style status and response body explicitly (ResultData comes from your app scaffold—import path depends on the template).
const function1 = async ({ payload }) => {
console.log("function1 is invoked");
const userName = payload.userName;
return {
"key1": "value1",
"key2": userName,
};
};

module.exports = { function1 };

Adjust payload usage to match what your app or caller sends (query body, event data, etc.).


Rules​

  • Manifest alignment: Every backend_api_functions key and every event handler must exist as a real export on server.js.
  • Validation: Run appnest-development-engine app validate before commits or in CI (lint + manifest checks).
  • Unused catch binding: If you do not use the error, use a parameterless catch { } (not catch (e) with an unused e).

Returning data to the frontend​

When the UI invokes a backend function, the client typically receives an object shaped like { statusCode, body }: statusCode is an HTTP-style code (e.g. 200, 400, 401); body is what the function returned. If your backend uses a ResultData({ body, statusCode }) (or equivalent) helper, those values flow through to the client; otherwise the framework may default statusCode (e.g. 200) and put a plain return value in body. Exact behavior can depend on your app template—test against your scaffold.

Example with ResultData:

const function2 = async ({ payload }) => {
console.log("function2 is invoked");
const userName = payload.userName;
return new ResultData({
body: {
message: 'Function 2 executed successfully..!!@@@@!!.',
userName,
},
statusCode: 200,
});
};

Wire function2 through module.exports like any other handler, and ensure ResultData is in scope (via require from your scaffold’s shared backend utilities).


Local dev note​

Under the dev proxy, backend traffic is usually available under paths such as /app-backend/.... You do not run a separate public HTTP server for normal Appnest local development.


Further reading (this site)​

TopicDocument
App shape & project layoutApp Overview
Manifest schema & installation_parametersManifest
Appnest FunctionsAppnest Functions overview
Engine & CLIDevelopment Engine overview, Commands