next.jsvercelapi-versioning

Managing API versions using nextjs and vercel


I'm starting to build out an API using nextjs with Vercel deployments. It's quite simple to get setup, simply create files under pages/api/. For example the create endpoints /shows, /movies, /sports I have:

./pages/api/
    /shows
    /movies
    /sports

This is fine, but I'd like to version the API like this: /v1/shows/, /v1/movies, etc.

Even better if I could version based on git commit tag. That is, when I merge to the main branch, Vercel either deploys to current production env (e.g. v1 env), or if there's a new git tag, it deploys to a new production env (e.g. v2 env). After deploying, two production environments will be live (v1 and v2) and hence old clients will not break.

Is there a way to do this with Vercel? Or is there a simpler approach I'm missing? How are other people handling API versioning using nextjs? I'm open to ideas!


Solution

  • If you want to use the same endpoints and serve a different response based on v1/v2, you can add rewrites to your next.config.js file.

    module.exports = {
      async rewrites() {
        return [
          {
            source: '/v/:version/:rest*',
            destination: '/api/:rest*?version=:version',
          }
        ]
      }
    }
    

    Then when you visit /v/1/shows, it will be the same as visiting /api/shows?version=1.

    That means you can check req.query.version in your API to determine the appropriate response.

    Update 2024: The answer above is good if you have public APIs. However, Next.js now has Server Actions which are effectively private APIs. Vercel has a feature called Skew Protection that protects from version skew (old client version requesting new server version). That means you can modify both client (for example a form) and server (for example the server action handling the form post) without explicitly setting a version or worrying about version skew errors.