All Projects → hoangvvo → Next Connect

hoangvvo / Next Connect

Licence: mit
The TypeScript-ready, minimal router and middleware layer for Next.js, Micro, Vercel, or Node.js http/http2

Programming Languages

javascript
184084 projects - #8 most used programming language
typescript
32286 projects

Projects that are alternatives of or similar to Next Connect

Connext Js
A middleware and route handling solution for Next.js.
Stars: ✭ 211 (-53.52%)
Mutual labels:  middleware, nextjs
koa-rest-router
Most powerful, flexible and composable router for building enterprise RESTful APIs easily!
Stars: ✭ 67 (-85.24%)
Mutual labels:  middleware, router
Mux
A powerful HTTP router and URL matcher for building Go web servers with 🦍
Stars: ✭ 15,667 (+3350.88%)
Mutual labels:  middleware, router
Webgo
A minimal framework to build web apps; with handler chaining, middleware support; and most of all standard library compliant HTTP handlers(i.e. http.HandlerFunc).
Stars: ✭ 165 (-63.66%)
Mutual labels:  middleware, router
Iris
The fastest HTTP/2 Go Web Framework. AWS Lambda, gRPC, MVC, Unique Router, Websockets, Sessions, Test suite, Dependency Injection and more. A true successor of expressjs and laravel | 谢谢 https://github.com/kataras/iris/issues/1329 |
Stars: ✭ 21,587 (+4654.85%)
Mutual labels:  middleware, router
Rayo.js
Micro framework for Node.js
Stars: ✭ 170 (-62.56%)
Mutual labels:  middleware, router
Golf
⛳️ The Golf web framework
Stars: ✭ 248 (-45.37%)
Mutual labels:  middleware, router
Http Router
🎉 Release 2.0 is released! Very fast HTTP router for PHP 7.1+ (incl. PHP8 with attributes) based on PSR-7 and PSR-15 with support for annotations and OpenApi (Swagger)
Stars: ✭ 124 (-72.69%)
Mutual labels:  middleware, router
Simple Php Router
Simple, fast and yet powerful PHP router that is easy to get integrated and in any project. Heavily inspired by the way Laravel handles routing, with both simplicity and expand-ability in mind.
Stars: ✭ 279 (-38.55%)
Mutual labels:  middleware, router
Frontexpress
An Express.js-Style router for the front-end
Stars: ✭ 263 (-42.07%)
Mutual labels:  middleware, router
Next Session
Simple promise-based session middleware for Next.js, micro, Express, and more
Stars: ✭ 161 (-64.54%)
Mutual labels:  middleware, nextjs
Krakend
Ultra performant API Gateway with middlewares. A project hosted at The Linux Foundation
Stars: ✭ 4,752 (+946.7%)
Mutual labels:  middleware, router
Pure Http
✨ The simple web framework for Node.js with zero dependencies.
Stars: ✭ 139 (-69.38%)
Mutual labels:  middleware, router
Routerify
A lightweight, idiomatic, composable and modular router implementation with middleware support for the Rust HTTP library hyper.rs
Stars: ✭ 173 (-61.89%)
Mutual labels:  middleware, router
Foxify
The fast, easy to use & typescript ready web framework for Node.js
Stars: ✭ 138 (-69.6%)
Mutual labels:  middleware, router
Clevergo
👅 CleverGo is a lightweight, feature rich and high performance HTTP router for Go.
Stars: ✭ 246 (-45.81%)
Mutual labels:  middleware, router
Dotweb
Simple and easy go web micro framework
Stars: ✭ 1,354 (+198.24%)
Mutual labels:  middleware, router
Gin
Gin is a HTTP web framework written in Go (Golang). It features a Martini-like API with much better performance -- up to 40 times faster. If you need smashing performance, get yourself some Gin.
Stars: ✭ 53,971 (+11787.89%)
Mutual labels:  middleware, router
Zen
zen is a elegant and lightweight web framework for Go
Stars: ✭ 257 (-43.39%)
Mutual labels:  middleware, router
Miox
Modern infrastructure of complex SPA
Stars: ✭ 374 (-17.62%)
Mutual labels:  middleware, router

next-connect

npm CircleCI codecov minified size download/year PRs Welcome

The smol method routing and middleware for other frameworks). Powered by trouter.

Features

  • Compatible with Express.js middleware and router => Drop-in replacement for Express.js.
  • Lightweight (~ 3KB) => Suitable for serverless environment.
  • 5x faster than Express.js with no overhead
  • Works with async handlers (with error catching)
  • TypeScript support

Installation

npm install next-connect
// or
yarn add next-connect

Usage

next-connect is often used in API Routes:

// pages/api/hello.js
import nc from "next-connect";

const handler = nc()
  .use(someMiddleware())
  .get((req, res) => {
    res.send("Hello world");
  })
  .post((req, res) => {
    res.json({ hello: "world" });
  })
  .put(async (req, res) => {
    res.end("async/await is also supported!");
  })
  .patch(async (req, res) => {
    throw new Error("Throws me around! Error can be caught and handled.");
  });

export default handler;

For quick migration from match multiple routes recipe.

For usage in pages with getServerSideProps, see .run.

See an example in nextjs-mongodb-app (CRUD, Authentication with Passport, and more)

TypeScript

By default, the base interfaces of req and res are IncomingMessage and ServerResponse. When using in API Routes, you would set them to NextApiRequest and NextApiResponse by providing the generics to the factory function like so:

import { NextApiRequest, NextApiResponse } from "next";
import nc from "next-connect";

const handler = nc<NextApiRequest, NextApiResponse>();

In each handler, you can also define custom properties to req and res (such as req.user or res.cookie) like so:

interface ExtendedRequest {
  user: string;
}
interface ExtendedResponse {
  cookie(name: string, value: string): void;
}

handler.post<ExtendedRequest, ExtendedResponse>((req, res) => {
  req.user = "Anakin";
  res.cookie("sid", "8108");
});

API

The API is similar to Express.js with several differences:

  • It does not include any helper methods or template engine (you can incorporate them using middleware).
  • It does not support error-handling middleware pattern. Use options.onError instead.

It is more like good ol' connect (hence the name) with method routing.

nc(options)

Initialize an instance of next-connect.

options.onError

Accepts a function as a catch-all error handler; executed whenever a middleware throws an error. By default, it responds with status code 500 and an error message if any.

function onError(err, req, res, next) {
  logger.log(err);

  res.status(500).end(err.toString());
  // OR: you may want to continue
  next();
}

const handler = nc({ onError });

handler
  .use((req, res, next) => {
    throw new Error("oh no!");
    // or use next
    next(Error("oh no"));
  })
  .use((req, res) => {
    // this will run if next() is called in onError
    res.end("error no more");
  });

options.onNoMatch

Accepts a function of (req, res) as a handler when no route is matched. By default, it responds with 404 status and not found body.

function onNoMatch(req, res) {
  res.status(404).end("page is not found... or is it");
}

const handler = nc({ onNoMatch });

options.attachParams

Passing true will attach params object to req. By default, it does not set to req.params.

const handler = nc({ attachParams: true });

handler.get("/users/:userId/posts/:postId", (req, res) => {
  // Visiting '/users/12/posts/23' will render '{"userId":"12","postId":"23"}'
  res.send(req.params);
});

.use(base, ...fn)

base (optional) - match all route to the right of base or match all if omitted.

fn(s) are functions of (req, res[, next]) or an instance of next-connect, where it will act as a sub application.

// Mount a middleware function
handler.use((req, res, next) => {
  req.hello = "world";
  next(); // call to proceed to next in chain
});

// Or include a base
handler.use("/foo", fn); // Only run in /foo/**

// Mount an instance of next-connect
const common = nc().use(midd1).use("/", midd2); // good for common middlewares
const auth = nc().use("/dashboard", checkAuth);
const subapp = nc().get(getHandle).post("/baz", postHandle).put("/", putHandle);
handler
  // `midd1` and `midd2` runs everywhere
  .use(common)
  // `checkAuth` only runs on /dashboard/*
  .use(auth)
  // `getHandle` runs on /foo/*
  // `postHandle` runs on /foo/baz
  // `putHandle` runs on /foo
  .use("/foo", subapp);

// You can use a library too.
handler.use(passport.initialize());

.METHOD(pattern, ...fns)

METHOD is a HTTP method (GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE) in lowercase.

pattern (optional) - match all route based on supported pattern or match all if omitted.

fn(s) are functions of (req, res[, next]). This is ideal to be used in API Routes.

handler.get("/api/user", (req, res, next) => {
  res.json(req.user);
});
handler.post("/api/users", (req, res, next) => {
  res.end("User created");
});
handler.put("/api/user/:id", (req, res, next) => {
  // https://nextjs.org/docs/routing/dynamic-routes
  res.end(`User ${req.query.id} updated`);
});
handler.get((req, res, next) => {
  res.end("This matches whatever route");
});

However, since Next.js already handles routing (including dynamic routes), we often omit pattern in .METHOD.

.all(pattern, ...fns)

Same as .METHOD but accepts any methods.

.run(req, res)

Runs req and res the middleware and returns a promise. It will not render 404 on not found or onError on error.

This can be useful in getServerSideProps.

// page/index.js
export async function getServerSideProps({ req, res }) {
  const handler = nc().use(passport.initialize()).post(postMiddleware);
  try {
    await handler.run(req, res);
  } catch (e) {
    // handle the error
  }
  // do something with the upgraded req and res
  return {
    props: { user: req.user },
  };
}

Recipes

Next.js

Match multiple routes

If you created the file /api/<specific route>.js folder, the handler will only run on that specific route.

If you need to create all handlers for all routes in one file (similar to Express.js). You can use Optional catch all API routes.

// pages/api/[[...slug]].js
import nc from "next-connect";

const handler = nc({ attachParams: true })
  .use("/api/hello", someMiddleware())
  .get("/api/user/:userId", (req, res) => {
    res.send(`Hello ${req.params.userId}`);
  });

export default handler;

While this allows quick migration from Express.js, consider seperating routes into different files (/api/user/[userId].js, /api/hello.js) in the future.

Using in other frameworks

next-connect supports any frameworks and runtimes that support (req, res) => void handler.

Micro
const { send } = require("micro");
const nc = require("next-connect");

module.exports = nc()
  .use(middleware)
  .get((req, res) => {
    res.end("Hello World!");
  })
  .post((req, res) => {
    send(res, 200, { hello: "world" });
  });
Vercel
const nc = require("next-connect");

module.exports = nc()
  .use(middleware)
  .get((req, res) => {
    res.send("Hello World!");
  })
  .post((req, res) => {
    res.json({ hello: "world" });
  });
Node.js HTTP / HTTP2 Server
const http = require("http");
// const http2 = require('http2');
const nc = require("next-connect");

const handler = nc()
  .use(middleware)
  .get((req, res) => {
    res.end("Hello world");
  })
  .post((req, res) => {
    res.setHeader("content-type", "application/json");
    res.end(JSON.stringify({ hello: "world" }));
  });

http.createServer(handler).listen(PORT);
// http2.createServer(handler).listen(PORT);

Contributing

Please see my contributing.md.

License

MIT

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].