Coder Social home page Coder Social logo

ivandotv / nextjs-koa-api Goto Github PK

View Code? Open in Web Editor NEW
10.0 1.0 1.0 347 KB

Koa.js framework setup to run within Next.js API routes.

License: MIT License

JavaScript 28.54% Shell 0.73% TypeScript 58.37% CSS 12.36%
koa-router koajs nextjs nextjs-api nextjs-api-routes

nextjs-koa-api's Introduction

Next.js Koa API

workflow status code coverage sofware licence

Introduction

Nextjs Koa API is a library that packages Koa.js framework for use with the Next.js API routes.

Motivation

Using 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.

So I decided to set up Koa.js to run inside the Next.js API route.

Why Koa

There 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 is superior to other frameworks. Koa.js source is very small and it can be initialized fast, which is important for a serverless function.

Installation

npm install nextjs-koa-api

Usage

This library bundles Koa.js and Koa 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.

The simplest example that would mimic the original Next.js api router is this:

//pages/api/[[...demo]].ts
import { KoaApi, withKoaApi } from 'nextjs-koa-api'

const api = new KoaApi({ router: { prefix: '/api' } })

api.use((ctx) => {
  ctx.body = 'Hello World'
})

//use helper function
export default withKoaApi(api)

//or the standard way
export default function handler(req: NextApiRequest, res: NextApiResponse) {
  return api.run(req, res)
}

KoaApi class extends Koa so all Koa methods are available. It does not modify Koa or override any of its methods.

Routing

When 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.

//pages/api/[[...demo]].ts
const api = new KoaApi({ router: { prefix: '/api' } })

api.router
  .get('/', (ctx, next) => {})
  .post('/', (ctx, next) => {})
  .delete('/', (ctx, next) => {})

In the above example the { prefix: '/api' } that is passed to the KoaApi instance is an option on the router that enables you to prefix the router routes with a part of the url. so instead of writing:

api.router.get('/api', (ctx, next) => {}).delete('/api', (ctx, next) => {})

we can write:

api.router.get('/', (ctx, next) => {}).delete('/', (ctx, next) => {})

If your api file is nested deep: pages/api/dir_one/dir_two/[[...]].ts using te prefix makes using routes a lot simpler: prefix: api/dir_one/dir_two.

You can also work with nested routes by creating and mounting new routers. You can get a new router like this:

import {Router} from 'nextjs-koa-api`

const router = new Router()

For more info check out Koa Router docs

Attaching a custom router

There 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()

import {Router, KoaApi,attachRouter} from 'nextjs-koa-api`

const api = new KoaApi()
const router = new Router()

router.get('/',(ctx,next)=>{

  ctx.body = 'hello'

  return next()
})

attachRouter('/some/deep-path',api, router)

Router options that are passed to the KoaApi are not associated with the custom router. They are only applicable to the default router that is created.

Nextjs request and response objects

Just 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

api.use((ctx) => {
  ctx.req // nextjs request
  ctx.res // nextjs response

  ctx.request //Koa request
  ctx.response // Koa response
})

Body data

Nextjs automatically parses incoming body data 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.

If you want to disable setting the body data on ctx.request.body you can do that while creating the KoaApi instance.

new KoaApi({ attachBody: false })

Typescript

This library exports everything from the Kao and Koa Router libraries, which includes all the types.

import { Koa, KoaApi, Router, withKoaApi } from 'nextjs-koa-api'

interface ApiState extends Koa.DefaultState {
  seesion: boolean
}
interface ApiContext extends Koa.Context {
  user: { name: string }
}
const api = new KoaApi<ApiState, ApiContext>()

api.use(async (ctx, next) => {
  ctx.user.name
  ctx.state.seesion
})

Testing

Testing can be done with supertest(https://github.com/visionmedia/supertest)

import request from 'supertest'

test('status is 200', async () => {
  const api = new KoaApi()

  api.router.get('/hello', (ctx) => {
    ctx.body = 'hello'
  })

  const result = await request(withKoaApi(api)).post('/hello')

  expect(result.status).toBe(200)
})

There 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.

Example

There is a example directory in this repository, which is a Next.js app with one exported api route that uses KoaApi.

License

This project is licensed under the MIT License - see the LICENSE file for details

Api Docs

Automatically generated API documentation can be found here

nextjs-koa-api's People

Contributors

github-actions[bot] avatar ivandotv avatar renovate-bot avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

nextjs-koa-api's Issues

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Rate-Limited

These updates are currently rate-limited. Click on a checkbox below to force their creation now.

  • Update codecov/codecov-action action to v4
  • Update dependency @types/node to v20
  • Update dependency @types/supertest to v6
  • Update dependency husky to v9
  • Update dependency jest-watch-typeahead to v2
  • Update dependency koa-body to v6
  • Update dependency lint-staged to v15
  • Update dependency prettier to v3
  • Update dependency typescript to v5
  • Update eslint packages (major) (eslint, eslint-config-next, eslint-config-prettier, eslint-plugin-jest, eslint-plugin-prettier)
  • Update pnpm/action-setup action to v3
  • Update stefanzweifel/git-auto-commit-action action to v5
  • Update typescript-eslint monorepo to v7 (major) (@typescript-eslint/eslint-plugin, @typescript-eslint/parser)
  • ๐Ÿ” Create all rate-limited PRs at once ๐Ÿ”

Other Branches

These updates are pending. To force PRs open, click the checkbox below.

  • Update dependency minimist to v1.2.6 [SECURITY]

Open

These updates have all been created already. Click a checkbox below to force a retry/rebase of any.

Ignored or Blocked

These are blocked by an existing closed PR and will not be recreated unless you click a checkbox below.

Detected dependencies

github-actions
.github/workflows/CI.yml
  • actions/checkout v2
  • actions/cache v2
  • actions/setup-node v2
  • pnpm/action-setup v2.2.2
  • codecov/codecov-action v3
  • changesets/action v1
  • stefanzweifel/git-auto-commit-action v4
lib/koa-api/.github/workflows/CI.yml
  • actions/checkout v2
  • actions/cache v2
  • actions/setup-node v2
  • pnpm/action-setup v2.2.1
  • codecov/codecov-action v2
  • changesets/action v1
  • stefanzweifel/git-auto-commit-action v4
npm
example/package.json
  • @koa/router ^10.1.1
  • koa ^2.13.4
  • koa-body ^5.0.0
  • next 12.1.6
  • nextjs-koa-api ^2.0.0
  • on-finished ^2.4.1
  • react 18.1.0
  • react-dom 18.1.0
  • @types/koa ^2.13.4
  • @types/koa__router ^8.0.11
  • @types/node ^17.0.30
  • @types/react 18.0.8
  • @types/react-dom 18.0.3
  • eslint ^8.14.0
  • eslint-config-next 12.1.6
  • typescript ^4.6.4
lib/koa-api/package.json
  • @koa/router ^10.1.1
  • koa ^2.13.4
  • on-finished ^2.4.1
  • @types/koa ^2.13.4
  • @types/koa__router ^8.0.11
  • @types/jest ^27.5.0
  • @types/node ^17.0.31
  • @types/on-finished ^2.3.1
  • @types/supertest ^2.0.12
  • @typescript-eslint/eslint-plugin ^5.22.0
  • @typescript-eslint/parser ^5.22.0
  • @babel/core ^7.17.10
  • @babel/preset-env ^7.17.10
  • @babel/preset-typescript ^7.16.7
  • cross-env ^7.0.3
  • eslint ^8.15.0
  • eslint-config-prettier ^8.5.0
  • eslint-plugin-jest ^26.1.5
  • eslint-plugin-prettier ^4.0.0
  • eslint-plugin-promise ^6.0.0
  • eslint-plugin-tsdoc ^0.2.16
  • jest ^28.1.0
  • jest-mock-console ^1.2.3
  • jest-watch-typeahead ^1.1.0
  • microbundle ^0.15.0
  • next 12.1.6
  • shx ^0.3.4
  • supertest ^6.2.3
  • typescript ^4.6.4
  • typedoc ^0.22.15
  • typedoc-plugin-markdown ^3.12.1
package.json
  • husky ^7.0.4
  • lint-staged ^12.2.2
  • prettier ^2.5.1
  • @changesets/cli ^2.19.0
  • del ^6.0.0
  • minimist ^1.2.5

  • Check this box to trigger a request for Renovate to run again on this repository

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.