/Vercel

Swift runtime for Vercel Serverless Functions

Primary LanguageSwiftMIT LicenseMIT

Vercel

A Swift runtime and SDK for Vercel Serverless Functions.

Vercel Starter Kit

Getting Started

Check out the intoductory blog post and YouTube tutorial for getting started:

How does this work?

There's two important pieces to this package that make everything work:

  1. An SDK that wraps the AWSLambdaRuntime and provides access to Vercel specific API like EdgeConfig
  2. A Swift Package Plugin which builds your code and produces a directory structure compliant with Vercel's Build Output API

Usage

Request Handler

import Vercel

@main
struct App: RequestHandler {

    func onRequest(_ req: Request) async throws -> Response {
        let greeting = EdgeConfig.default.get("greeting").string!
        return .status(.ok).send("Hello, \(greeting)")
    }
}

Express Handler

import Vercel

@main
struct App: ExpressHandler {

    static func configure(router: isolated Router) async throws {
        router.get("/") { req, res in
            res.status(.ok).send("Hello, Swift")
        }
    }
}

Vapor Handler

import Vapor
import VercelVapor

@main
struct App: VaporHandler {

    static func configure(app: Application) async throws {
        app.get { _ in
            "Hello, Vapor"
        }
    }
}

And make sure to update your Package.swift with the new package:

dependencies: [
  .product(name: "Vercel", package: "Vercel"),
  .product(name: "VercelVapor", package: "Vercel")
]

Data Fetching

You can use any popular library to fetch data such as Alamofire or async-http-client but we also provide a convenient fetch() method directly in this package:

let obj = try await fetch("https://httpbin.org/json").json()

Edge Config

This package provides full access to Vercel's Edge Config API. You can access the default edge config store or any additional store assigned to your project:

// Default edge config
let str = EdgeConfig.default.get("some-string-key").string

// Edge config assigned to an environment variable
let num = EdgeConfig("EDGE_CONFIG_2").get("some-int-key").int

Static Files

You can add a top level public folder that will be deployed statically to Vercel's CDN.

Cron Jobs

Cron jobs are fully supported by adding a vercel.json file to the root of your project and following the Vercel documentation here: https://vercel.com/docs/cron-jobs

Running Locally

Running server side locally has traditionally been a huge pain, but not anymore. This package makes it trivial to run code locally:

swift package --disable-sandbox vercel dev

This will build and run your Swift application and start a local server at http://localhost:7676

Deploy

Locally

To deploy your project locally you need to install Docker and the Vercel CLI. Once installed you can you must link your Vercel project:

vercel link

After linking your project you can deploy it via Swift package manager:

swift package --disable-sandbox vercel deploy

Deploy Options

swift package --disable-sandbox vercel deploy
  • --prod - Triggers a production deploy to Vercel
  • --product <name> - The product you want to build. Default: first target in Package.swift with the Vercel dependency
  • --memory <number> - The amount of memory in megabytes to allocate to your function. Default 512mb
  • --duration <number> - The maximum duration in seconds that your function will run. Default: 10s
  • --regions <name> - Comma separated list of regions to deploy your function to. Default: iad1
  • --port <number> - Custom port to run the local dev server on. Default: 7676

GitHub Actions

Use the following GitHub actions workflow to continuiously deploy your project to Vercel:

name: Vercel

on:
  push:
    branches:
      - main

env:
  VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
  VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
  VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}

jobs:
  deploy:
    runs-on: ubuntu-latest
    container: swift:5.10-amazonlinux2

    steps:
      - uses: actions/checkout@v3

      - uses: actions/cache@v3
        with:
          path: .build
          key: ${{ runner.os }}-spm-${{ hashFiles('Package.resolved') }}
          restore-keys: |
            ${{ runner.os }}-spm-

      - uses: actions/setup-node@v3
        with:
          node-version: 16

      - name: Install
        run: npm install -g vercel@latest

      - name: Deploy
        run: swift package --disable-sandbox vercel deploy