Skip to content

exiguus/serverless-express-vercel

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

12 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Serverless Express Vercel

Vercel Serverless RESTfull API example. Using Express.js and Vercel Serverless functions.

Intention

As a foundation, Express enables the swift migration of pre-existing applications and also supports the utilization of existing extensions from the Express ecosystem.

While Vercel's Serverless capabilities empower the utilization of the Vercel platform, offering a multitude of advantages such as the ability to run AWS Serverless functions in various regions, preview deployments, and versatile runtime protocols. Furthermore, it facilitates seamless integration with GitHub.

Structure

serverless on ξ‚  main [!] is πŸ“¦ v1.0.0 via  v18.16.0 via πŸ’Ž v3.0.0
❯ tree -d -C --gitignore -v
.
β”œβ”€β”€ api
β”œβ”€β”€ assets
β”‚   β”œβ”€β”€ redoc
β”‚   └── swagger
β”œβ”€β”€ public
β”‚   β”œβ”€β”€ redoc
β”‚   └── swagger
β”œβ”€β”€ scripts
β”œβ”€β”€ src
β”‚   β”œβ”€β”€ middleware
β”‚   β”œβ”€β”€ router
β”‚   β”œβ”€β”€ schema
β”‚   β”œβ”€β”€ service
β”‚   └── utils
└── tests

16 directories

Features

Solutions

Setup

Prerequisites:

  • pnpm npm i -g pnpm

Install dependencies:

pnpm i

Update dependencies:

pnpm up

The pnpm install hook updates includeFiles in the vercel.json file.

Development

Nodemon is used to watch for changes and restart the server. Tsc is used to compile the TypeScript code.

pnpm dev

Test

Eslint is used to lint the code.

pnpm lint

Jest is used to run the tests. pnpm test

Playwright is used to run the e2e tests.

pnpm e2e

Build

Tsc is used to compile the TypeScript code. The swagger documentation is generated from the OpenAPI specification in the openapi.yml file.

pnpm build

Pre-Commit and Pre-Push Hooks

The pre-commit and pre-push hooks are configured with the [husky] The pre-commit hook runs the lint and generates the documentation. The pre-push hook runs a test build.

APIs

Documentation

Visit http://localhost:8000/redoc and http://localhost:8000/swagger to see the documentation.

OpenAPI

https://spec.openapis.org/oas/v3.0.2

The Openapi specification is used to generate the API documentation.

Update the openapi.yml file and run pnpm build:docs to update the API documentation.

The openapi.yml file is used to generate the swagger.json file for the Swagger documentation.

Redoc

The script copy the current version of the openapi.yml file for the documentation. Also copy all the assets.

Swagger

The script generate the swagger.json from the current openapi.yml and copy the current version of the swagger.json file for the documentation. Also copy all the assets.

Authentication

Generate a JWT token

serverless on ξ‚  main [!?] is πŸ“¦ v1.0.0 via  v18.16.0 via πŸ’Ž v3.0.0
❯ node scripts/generateJWToken.mjs
header.payload.secret

Deployment

https://vercel.com/docs/deployments/overview

Using the Node.js Runtime for Serverless Functions from Vercel. Use the "functions" field in vercel.json to configure the serverless function entry point. The entry point must be moved to a api subfolder.

{
  "functions": {
    "api/index.ts": {
      "memory": 1024,
      "maxDuration": 10,
      "includeFiles": "{{src,public}/**,{src,public}/**/**,package.json,node_modules/{ajv,apicache,axios,compression,cors,dotenv,express,express-jwt}/**,node_modules/{ajv,apicache,axios,compression,cors,dotenv,express,express-jwt}/**/**,}",
      "excludeFiles": "{src/**/*.test.ts,src/**/**/.test.ts}"
    }
  },
  "trailingSlash": true,
  "rewrites": [
    {
      "source": "/swagger/",
      "destination": "/swagger/index.html"
    },
    {
      "source": "/redoc/",
      "destination": "/redoc/index.html"
    },
    {
      "source": "/(.*)",
      "destination": "api/index.ts"
    }
  ]
}

Legacy Version

Use "builds" instead of "functions" in vercel.json. The entry point must be moved to the src subfolder.

{
  "builds": [
    {
      "src": "src/index.ts",
      "use": "@vercel/node",
      "config": {
        "includeFiles": [
          "src/**",
          "public/**",
          "package.json",
          "node_modules/ajv/**",
          "node_modules/apicache/**",
          "node_modules/axios/**",
          "node_modules/compression/**",
          "node_modules/cors/**",
          "node_modules/dotenv/**",
          "node_modules/express/**",
          "node_modules/express-jwt/**"
        ],
        "excludeFiles": ["src/**/*.test.ts"]
      }
    }
  ],
  "rewrites": [
    {
      "source": "/(.*)",
      "destination": "src/index.ts"
    }
  ]
}

However, in the legacy version, it is also possible to use a JavaScript file as entry point.

{
    "builds": [
        {
-           "src": "index.ts",
+           "src": "dist/api/index.js",
            "use": "@vercel/node",
            "config": {
                "includeFiles": [
-                   "**"
+                   "dist/**"
                ]
            }
        }
    ],
    "routes": [
        {
            "src": "/(.*)",
-           "dest": "index.ts"
+           "dest": "dist/api/index.js"
        }
    ]
}

But then you need to build the project first. And the dist folder must be checked in. This can be automated with a git pre-commit hook. For example with the pnpm 'pre-commit' package. That allow to add a pre-commit field in the package.json

    "scripts": {
+      "build:add": "git add dist -f",
    },
+  "pre-commit": [
+      "check",
+      "build",
+      "build:add"
+  ]

Generate the vercel.json file

pnpm run vercel:generate

or

serverless on ξ‚  main [!] is πŸ“¦ v1.0.0 via  v18.16.0 via πŸ’Ž v3.0.0
❯ node scripts/generateVercelJson.mjs
Generate vercel.json
Generate vercel.json include dependencies {{src,public}/**,{src,public}/**/**,package.json,node_modules/{ajv,apicache,axios,compression,cors,dotenv,express,express-jwt}/**,node_modules/{ajv,apicache,axios,compression,cors,dotenv,express,express-jwt}/**/**,}

Releases

No releases published

Packages

No packages published