0.3.0 • Published 1 year ago

@whatwg-node/router v0.3.0

Weekly downloads
-
License
MIT
Repository
github
Last release
1 year ago

Platform agnostic JavaScript HTTP Router

npm version License: MIT

@whatwg-node/router is a package that allows you to create modern JavaScript HTTP router with the WHATWG Fetch API that works in any JavaScript environment including Node.js, Deno, Bun, Cloudflare Workers, Next.js, Fastify, Express, AWS Lambdas and even in browsers.

Installation

yarn add @whatwg-node/router

Why should I use this package instead of other packages like itty-router, express or fastify?

There are many packages out there that allow you to create HTTP routers, but they are not platform agnostic. They are only for Node.js or only for those specific environments. But if you use this package, your router will work in any environment that uses JavaScript.

Usage

It follows the similar pattern to the express package, so basically you create a Router instance and extend it with routers by using the HTTP methods like get, post, put, patch, delete, head and options. And there is also all method that allows you to match all HTTP methods.

The first argument of these methods is the url pattern, and the following functions are handlers or middlewares that will be called when the request matches the pattern.

Note: The url pattern is a string that follows the URLPattern standard. You can learn more about URL patterns here.

Router gives you an extended version of the regular Request object that has the following properties:

  • request.params: An object that contains the parameters that are given in the url pattern.
  • request.query: An object that contains the query parameters that are given in the url.

Let's create a basic REST API that manages users.

import { createRouter, Response } from '@whatwg-node/router'

const router = createRouter()

const users = [
  { id: '1', name: 'John' },
  { id: '2', name: 'Jane' }
]

router.get('/users', request => Response.json(users))

// Parameters are given in the `request.params` object
router.get('/users/:id', request => {
  const user = users.find(user => user.id === request.params.id)

  if (!user) {
    return new Response(null, {
      status: 404
    })
  }

  return Response.json(user)
})

router.delete('/users/:id', request => {
  const user = users.find(user => user.id === request.params.id)

  if (!user) {
    return new Response(null, {
      status: 404
    })
  }

  users.splice(users.indexOf(user), 1)

  return new Response(null, {
    status: 204
  })
})

// Handle JSON bodies
router.put('/users', async request => {
  const body = await request.json()

  const user = {
    id: String(users.length + 1),
    name: body.name
  }

  users.push(user)

  return Response.json(user)
})

// Handle both parameters and JSON body
router.post('/users/:id', async request => {
  const user = users.find(user => user.id === request.params.id)

  if (!user) {
    return new Response(null, {
      status: 404
    })
  }

  const body = await request.json()

  user.name = body.name

  return Response.json(user)
})

Middlewares

You can also use middlewares to handle requests. Middlewares are functions that are called before the request is handled by the router. You can use them to handle authentication, logging, etc.

If a handler function doesn't return a Response object, the request will be passed to the next handler.

// In the following example, we are checking if the request has an `Authorization` header.
router.all('*', request => {
  if (!request.headers.get('Authorization')) {
    return new Response(null, {
      status: 401
    })
  }
})
router.get('/users', request => {
  // It doesn't reach here if the request doesn't have an `Authorization` header.
})

Handler chaining

You can also chain multiple handlers to a single route. In the following example, we are checking if the request has an Authorization header and if the user is an admin.

import { RouteHandler } from '@whatwg-node/router'

const withAuth: RouteHandler = request => {
  if (!request.headers.get('Authorization')) {
    return new Response(null, {
      status: 401
    })
  }
}

router.get('/users', withAuth, request => {
  // It doesn't reach here if the request doesn't have an `Authorization` header.
})

Error handling

If an unexpected error is thrown, the response will have a 500 status code. You can use the try/catch method to handle errors.

router.get('/users', request => {
  try {
    // Do something
  } catch (error) {
    return new Response('I handled the error gracefully', {
      status: 500
    })
  }
})

Usage in environments

Router is actually an instance of ServerAdapter of @whatwg-node/server package. So you can use it in any environment just like ServerAdapter. See the documentation of @whatwg-node/server package for more information.

0.3.0

1 year ago

0.2.7

1 year ago

0.2.6

1 year ago

0.2.5

1 year ago

0.2.4

1 year ago

0.2.3

1 year ago

0.2.2

1 year ago

0.2.1

1 year ago

0.2.0

1 year ago

0.1.10

1 year ago

0.1.9

1 year ago

0.1.8

1 year ago

0.1.7

1 year ago

0.1.6

1 year ago

0.1.5

1 year ago

0.1.4

1 year ago

0.1.3

1 year ago

0.1.2

1 year ago

0.1.1

1 year ago

0.1.0

1 year ago

0.0.3

1 year ago

0.0.2

1 year ago

0.0.1

1 year ago