{"id":14989406,"url":"https://github.com/ivandotv/nextjs-koa-api","last_synced_at":"2025-10-23T16:42:28.907Z","repository":{"id":36986199,"uuid":"488709474","full_name":"ivandotv/nextjs-koa-api","owner":"ivandotv","description":"Koa.js framework setup to run within Next.js API routes.","archived":false,"fork":false,"pushed_at":"2024-04-13T13:59:36.000Z","size":347,"stargazers_count":10,"open_issues_count":12,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-04-14T04:12:15.646Z","etag":null,"topics":["koa-router","koajs","nextjs","nextjs-api","nextjs-api-routes"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ivandotv.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2022-05-04T18:54:58.000Z","updated_at":"2024-04-15T23:40:30.631Z","dependencies_parsed_at":"2023-11-16T11:27:58.793Z","dependency_job_id":"e203fcf4-8882-4542-9c46-c81cddba4714","html_url":"https://github.com/ivandotv/nextjs-koa-api","commit_stats":{"total_commits":49,"total_committers":4,"mean_commits":12.25,"dds":"0.26530612244897955","last_synced_commit":"0534e92e704468aa461ec8d7921e603086dd4ce7"},"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ivandotv%2Fnextjs-koa-api","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ivandotv%2Fnextjs-koa-api/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ivandotv%2Fnextjs-koa-api/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ivandotv%2Fnextjs-koa-api/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ivandotv","download_url":"https://codeload.github.com/ivandotv/nextjs-koa-api/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248501414,"owners_count":21114674,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["koa-router","koajs","nextjs","nextjs-api","nextjs-api-routes"],"created_at":"2024-09-24T14:18:18.599Z","updated_at":"2025-10-23T16:42:23.859Z","avatar_url":"https://github.com/ivandotv.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Next.js Koa API\n\n\u003ca href=\"https://img.shields.io/github/workflow/status/ivandotv/nextjs-koa-api/Test\"\u003e\u003cimg src=\"https://img.shields.io/github/workflow/status/ivandotv/nextjs-koa-api/Test\" alt=\"workflow status\"\u003e\u003c/a\u003e\n\u003ca href=\"https://app.codecov.io/gh/ivandotv/nextjs-koa-api\"\u003e\u003cimg src=\"https://img.shields.io/codecov/c/gh/ivandotv/nextjs-koa-api\" alt=\"code coverage\"\u003e\u003c/a\u003e\n\u003ca href=\"https://github.com/ivandotv/nextjs-koa-api/blob/main/LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/github/license/ivandotv/nextjs-koa-api\" alt=\"sofware licence\"\u003e\u003c/a\u003e\n\n\u003c!-- toc --\u003e\n\n- [Introduction](#introduction)\n- [Motivation](#motivation)\n  - [Why Koa](#why-koa)\n- [Installation](#installation)\n- [Usage](#usage)\n  - [Routing](#routing)\n  - [Attaching a custom router](#attaching-a-custom-router)\n  - [Nextjs request and response objects](#nextjs-request-and-response-objects)\n    - [Body data](#body-data)\n- [Typescript](#typescript)\n- [Testing](#testing)\n- [Example](#example)\n- [License](#license)\n- [Api Docs](#api-docs)\n\n\u003c!-- tocstop --\u003e\n\n## Introduction\n\nNextjs Koa API is a library that packages [Koa.js](https://github.com/koajs/koa) framework for use with the Next.js API routes.\n\n## Motivation\n\nUsing Next.js routes is pretty straightforward, however, doing something like REST API with CRUD routes requires a more complicated setup. You end up using the `switch` statement to check which `http method` is used and then which `url` is requested, and soon you end up with a spaghetti code in your API route that is hard to maintain and test. It would be great if we could use tried and tested `HTTP` framework directly inside the routes.\n\nSo I decided to set up Koa.js to run inside the Next.js API route.\n\n### Why Koa\n\nThere are a lot of frameworks in Node.js land for handling HTTP responses, I've decided on Koa.js because it supports `async` middleware out of the box. And the way the middleware is run via the [`onion model`](https://itnext.io/how-koa-middleware-works-f4386b5573c) is superior to other frameworks.\nKoa.js source is very small and it can be initialized fast, which is important for a serverless function.\n\n## Installation\n\n```sh\nnpm install nextjs-koa-api\n```\n\n## Usage\n\nThis library bundles [Koa.js](https://github.com/koajs/koa) and [Koa router](https://github.com/koajs/router) in one easy to use class. It is important to note that nothing is changed in regards to working with Koa or Koa Router.\n\nThe simplest example that would mimic the original Next.js api router is this:\n\n```ts\n//pages/api/[[...demo]].ts\nimport { KoaApi, withKoaApi } from 'nextjs-koa-api'\n\nconst api = new KoaApi({ router: { prefix: '/api' } })\n\napi.use((ctx) =\u003e {\n  ctx.body = 'Hello World'\n})\n\n//use helper function\nexport default withKoaApi(api)\n\n//or the standard way\nexport default function handler(req: NextApiRequest, res: NextApiResponse) {\n  return api.run(req, res)\n}\n```\n\n`KoaApi` class extends `Koa` so all `Koa` methods are available. It does not modify Koa or override any of its methods.\n\n### Routing\n\nWhen you create a new `KoaApi` instance you have `Koa Router` available as the `router` property on the instance. The router is connected to the `KoaApi` instance so all that is left is to attach the routes.\n\n```ts\n//pages/api/[[...demo]].ts\nconst api = new KoaApi({ router: { prefix: '/api' } })\n\napi.router\n  .get('/', (ctx, next) =\u003e {})\n  .post('/', (ctx, next) =\u003e {})\n  .delete('/', (ctx, next) =\u003e {})\n```\n\nIn the above example the `{ prefix: '/api' }` that is passed to the `KoaApi` instance is an option on the router that enables you to prefix\nthe router routes with a part of the `url`.\nso instead of writing:\n\n```ts\napi.router.get('/api', (ctx, next) =\u003e {}).delete('/api', (ctx, next) =\u003e {})\n```\n\nwe can write:\n\n```ts\napi.router.get('/', (ctx, next) =\u003e {}).delete('/', (ctx, next) =\u003e {})\n```\n\nIf your api file is nested deep: `pages/api/dir_one/dir_two/[[...]].ts`\nusing te prefix makes using routes a lot simpler: `prefix: api/dir_one/dir_two`.\n\nYou can also work with [nested routes](https://github.com/koajs/router/blob/master/API.md#nested-routers) by creating and mounting new routers.\nYou can get a new router like this:\n\n```\nimport {Router} from 'nextjs-koa-api`\n\nconst router = new Router()\n```\n\nFor more info check out [Koa Router docs](https://github.com/koajs/router/blob/master/API.md#nested-routers)\n\n### Attaching a custom router\n\nThere is a convenient function for attaching a custom router. Internally it sets the `prefix` path on the router,and calls `router.routes()` and `router.allowedMethods()`\n\n```ts\nimport {Router, KoaApi,attachRouter} from 'nextjs-koa-api`\n\nconst api = new KoaApi()\nconst router = new Router()\n\nrouter.get('/',(ctx,next)=\u003e{\n\n  ctx.body = 'hello'\n\n  return next()\n})\n\nattachRouter('/some/deep-path',api, router)\n\n```\n\n\u003e Router options that are passed to the `KoaApi` are not associated with the custom router. They are only\n\u003e applicable to the _default_ router that is created.\n\n### Nextjs request and response objects\n\nJust like in the regular Kao.js app where the Node `request` and `response` objects are available on the `context` object via the `req` and `res` properties, the same is with the `KoaApi`\n\n```ts\napi.use((ctx) =\u003e {\n  ctx.req // nextjs request\n  ctx.res // nextjs response\n\n  ctx.request //Koa request\n  ctx.response // Koa response\n})\n```\n\n#### Body data\n\nNextjs automatically [parses incoming body data](https://nextjs.org/docs/api-routes/api-middlewares) and sets it up on the `req.body`. With `KoaApi` data from the `req.body`(`ctx.req`) will also be available on the `ctx.request.body`. That means that for most cases you don't need other body parsing middleware.\n\nIf you want to disable setting the `body data` on `ctx.request.body` you can do that while creating the `KoaApi` instance.\n\n```ts\nnew KoaApi({ attachBody: false })\n```\n\n## Typescript\n\nThis library exports everything from the Kao and Koa Router libraries, which includes all the types.\n\n```ts\nimport { Koa, KoaApi, Router, withKoaApi } from 'nextjs-koa-api'\n\ninterface ApiState extends Koa.DefaultState {\n  seesion: boolean\n}\ninterface ApiContext extends Koa.Context {\n  user: { name: string }\n}\nconst api = new KoaApi\u003cApiState, ApiContext\u003e()\n\napi.use(async (ctx, next) =\u003e {\n  ctx.user.name\n  ctx.state.seesion\n})\n```\n\n## Testing\n\nTesting can be done with `supertest`(https://github.com/visionmedia/supertest)\n\n```ts\nimport request from 'supertest'\n\ntest('status is 200', async () =\u003e {\n  const api = new KoaApi()\n\n  api.router.get('/hello', (ctx) =\u003e {\n    ctx.body = 'hello'\n  })\n\n  const result = await request(withKoaApi(api)).post('/hello')\n\n  expect(result.status).toBe(200)\n})\n```\n\nThere is also `@shopify/jest-koa-mocks`(https://github.com/Shopify/quilt/blob/main/packages/jest-koa-mocks/README.md) to easily stub Koa context and cookies.\n\n## Example\n\nThere is a [example](./example/) directory in this repository, which is a Next.js app with one exported api route that uses `KoaApi`.\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details\n\n## Api Docs\n\nAutomatically generated API documentation can be found [here](./lib//koa-api/docs/api/README.md)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fivandotv%2Fnextjs-koa-api","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fivandotv%2Fnextjs-koa-api","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fivandotv%2Fnextjs-koa-api/lists"}