1

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!

b.lyte
  • 6,518
  • 4
  • 40
  • 51
  • One way I'm thinking of managing this is creating branches for each version. So my `main` branch will actually be a development branch. Anytime I merge the changes to the `v1` branch, that preview deployment will be made (I'll ensure to include correct environment variables so that it deploys like a production app). Then when I need to create `v2` I simply make a corresponding `v2` branch. – b.lyte Dec 04 '20 at 20:09
  • Why not use the directory structure? For example, `./pages/api/v1/shows` and `./pages/api/v2/shows`? – styfle Dec 10 '20 at 00:34
  • This would require us to copy over the entire directory from v1/ to v2/ anytime we update. Maintaining two directories of code.. I don't really like that.. I actually like the setup we have so far which is to use version named branches (v1, v2, etc) – b.lyte Dec 10 '20 at 04:30

2 Answers2

8

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.

styfle
  • 22,361
  • 27
  • 86
  • 128
  • This is a great solution. Having a single directory for endpoints. Switch based on the version passed in if and only if that endpoint was modified in the latest version. This way we can iteratively upgrade endpoints as needed. Very cool! – b.lyte Jul 31 '23 at 14:12
0

You can create separate API versions like /api/v1 and /api/v2 for different endpoints.

- pages
  - api
    - v1
      - songs.js
    - v2
      - customers.js

And sure you should return the version number to client

// pages/api/v1/songs.js

export default function handler(req, res) {
  // Your logic for /api/v1/songs endpoint
  res.status(200).json({ version: "v1", message: "Songs endpoint for API version 1" });
}
// pages/api/v2/customers.js

export default function handler(req, res) {
  // Your logic for /api/v2/customers endpoint
  res.status(200).json({ version: "v2", message: "Customers endpoint for API version 2" });
}

At client side, the API should be called like

/api/v1/songs
/api/v2/customers
BS W
  • 1