Writing APIs (Beta)

You can create node.js/typescript APIs using Stormkit.

API Hello World

How it works

During build time, Stormkit checks if there is a .stormkit/api folder. When the folder is found, it uploads the folder to a lambda function. The entry file of the function then takes the Request and calls the relevant file based on file system routing. If nothing is found, it returns 404.

Write and deploy your API

Create an /api folder in the top level of your repository and an /index.ts file in it. Each file is treated as a separate endpoint and it needs to export a default function with the signature shown below.

// api/index.ts
import http from "http";

export default (req: http.IncomingMessage, res: http.ServerResponse) => {
  res.write("Function endpoint: /api");
  res.end();
};
// api/user/subscribe.ts
import http from "http";

export default (req: http.IncomingMessage, res: http.ServerResponse) => {
  res.write("Function endpoint: /api/user/subscribe");
  res.end();
};

The table below shows how the API routing works.

+ /api
  - index.ts        // /api
  + /users
    - index.ts      // /api/users
    - subscribe.ts  // /api/users/subscribe
    - create.ts     // /api/users/create
    + /[id]
      - remove.ts   // /api/users/:id/remove (where :id is a placeholder for dynamic values)

info
For more details on how the filesystem routing works, check the source code of the matchPath function.

Now go ahead and deploy your application. When Stormkit detects an /api source folder, it checks whether it is already built or not. If the /api folder is not yet built, Stormkit tries to build your api using Webpack and then deploys the output to the lambda function. This process is automatic.

Matching endpoints by request method

By default, files are matched through all requests. If you want to restrict certain endpoints with a request method, you can specify the method in the file name, right before the extension.

+ /api
  - index.ts            // ALL /api
  + /users
    - index.get.ts      // GET /api/users
    - index.post.ts     // POST /api/users
    - subscribe.ts      // ALL /api/users/subscribe
    + /[id]
      - index.delete.ts // DELETE /api/users/:id

Custom builds

If your source code contains more complex use cases and Stormkit fails to build, you can build the source code yourself. Here's the webpack config Stormkit uses to build the api. You can copy this and extend it based on your needs.

import type { Configuration } from "webpack";
import * as webpack from "webpack";
import * as path from "path";
import * as dotenv from "dotenv";
import { glob } from "glob";

const config: Configuration = {
  mode: "production",
  target: "node",

  // Iterate over the `api` subfolder and create an entry file
  // for each `.ts` file. This will tell webpack to create a bundle
  // for each function.
  entry: glob.sync("./api/**/*.{js,ts,tsx}").reduce((acc, file) => {
    acc[file.replace(/^\.\/api\//, "").split(".ts")[0]] = file;
    return acc;
  }, {}),

  output: {
    filename: "[name].js",
    // Build into `.stormkit/api` - Stormkit will take care of the rest.
    path: path.resolve(__dirname, ".stormkit/api"),
    // We need to use commonjs so that webpack exports the functions.
    library: {
      type: "commonjs",
    },
  },

  module: {
    rules: [
      {
        test: /\.ts$/,
        loader: "ts-loader",
        options: {
          compilerOptions: {
            noEmit: false,
          },
        },
      },
    ],
  },

  resolve: {
    extensions: [".tsx", ".ts", ".js"],
  },

  // Inject .env variables into the bundles.
  plugins: [
    new webpack.DefinePlugin(
      Object.keys(dotenv.config() || {}).reduce((obj, key) => {
        obj[`process.env.${key}`] = JSON.stringify(process.env[key]);
        return obj;
      }, {})
    ),
  ],
};

export default config;

Testing locally

In order to test the API locally go ahead and install the @stormkit/serverless package.

npm i -D @stormkit/serverless

Update package.json:

{
  "scripts": {
    "dev:api": "SERVERLESS_PORT=9090 node ./node_modules/@stormkit/serverless/dist/dev-server.js"
  }
}

And run the script:

npm run dev:api

You can access the api from http://localhost:9090/api.