next-sugar v0.1.0
next-sugar
A simple way to organize your next API route handlers.
Installation
npm install next-sugar
Usage
// file: src/pages/api/users.ts
import { get, post, handle, Response, StatusCodes } from "next-sugar";
import { prisma } from "src/db";
const postUser = post(async (request) => {
const body = await request.json();
return Response.json(body, StatusCodes.CREATED);
});
const listUsers = get(async (request) => {
const users = await prisma.user.findMany();
return Response.json(users);
});
export default handle(postUsers, listUsers);
You should disable the default body parsing of Next.js to delegate that task to request.json()
.
// file: src/pages/api/users.ts
export const config: PageConfig = {
api: {
bodyParser: false,
},
};
NOTE: One drawback is that Next.js currently do not support disabling body parsing globally, so you have to specify it manually on every api route.
Why do I need this?
Mostly, this is syntactic sugar. But it also provides a way for you to separate your request handlers
from your actual routes so you can write them and test them in isolation. Consider this:
// file: src/rest/postUser.ts
import { post, Response, StatusCodes } from "next-sugar";
export const postUser = post(async (request) => {
// ... some logic
return Response.empty(StatusCodes.CREATED);
});
And then in your actual api route:
// file: src/routes/api/users.ts
import { handle } from "next-sugar";
import { postUser } from "src/rest/postUser";
export default handle(postUser);
Also, it has built-in automatic error handling. You can still write your own try-catch
blocks if you need more granular control over the response.
Last but not least, I hate having to write if-else
blocks for handling different http methods like so:
const handler: NextApiHandler = (req, res) => {
if (req.method === "POST") {
// do something
} else if (req.method === "GET") {
// do something else
} else {
// some fallback
}
};
API
Request
.arrayBuffer(): Promise<ArrayBuffer>
.buffer(): Promise<Buffer>
.json(): Promise<unknown>
.text(): Promise<text>
Response
#buffer(buf: Buffer, init?: ResponseInit?): Response
#empty(status?: StatusCodes, headers?: Record<string, strin>): Response
#json(data: unknown, init?: ResponseInit): Response
#stream(readable: Readable, init?: ResponseInit): Response
#text(data: string, init?: ResponseInit): Response
4 years ago