nextjs-backend-helpers
v0.0.18-9
Published
A collection of helpers designed to make fullstack NextJS services easier to create. There are helpers to register API style `controllers`, a database `Repository` class designed to work with [`Prisma`](https://www.prisma.io/), and even testing tools.
Downloads
91
Readme
nextjs-backend-helpers
A collection of helpers designed to make fullstack NextJS services easier to create. There are helpers to register API style controllers
, a database Repository
class designed to work with Prisma
, and even testing tools.
The Problem
The NextJS Documentation says "you can build your entire API with API Routes.", but writing API routes in NextJS sucks. Here is an example handler for a post request:
export default function handler(req, res) {
if (req.method === 'POST') {
// Process a POST request
} else {
// Handle any other HTTP method
}
}
While this is fine for simple routes, it's easy to see how this doesn's scale.
The Solution
nextjs-backend-helpers
exports a number of use classes and functions to make not suck.
Controllers
To create a class based controller, simply extend the Controller
base class and install
it.
Controller
s support middleware through their before
and after
methods.
Kitchen Sink Example
export class AppController extends Controller {
constructor() {
super()
this.rescue(PrismaClientInitializationError, (error, request, response) => {
Logger.error({
message: 'Looks like we cant reach the database.'
+ 'Is the connection string right?'
+ 'Is the database up?',
})
response.status(500).json({
errors: ['unable to reach database'],
})
})
this.rescue(Error, (error, _request, response) => {
response.status(500).json({
errors: [error.constructor.name, error.message],
})
})
}
}
type UserIdQuery = {
id: string
}
type UserBody = {
name: string,
birthday: date
}
type Response = {
id: string,
name: string
}
export class UserController extends AppController {
constructor() {
super()
this.before((req: NextApiRequest) => {
console.log(Cookie.get('secret-cookie-value'))
}).only('get')
this.after(() => {
console.log('im running after the post action has run')
}).only('post')
}
async get(request: NextApiRequest, response: NextApiResponse<Response>) {
//...
const {id} = getQuery<UserIdQuery>(request)
const {name, birthday} = getBody<UserBody>(request)
const cookieValue = Cookie.get('secret-cookie-value')
//..
response.json({
id,
name,
cookieValue
})
}
}
We also have test helpers
// don't import the default export, but the named export
import { UserController, RequestBuilder } from './user-controller.ts'
import { get, ReponseType, RequestBuilder } from 'nextjs-backend-helpers'
describe('UserController', () => {
describe('returns a user', () => {
let response: ResponseType
let request: RequestBuilder
let user: User
beforeEach(async () => {
request = RequestBuilder().query({
id: '123'
})
response = await get(UserController, request)
})
it("returns the requested user", () => {
expect(response.json).toEqual({
data: {
id: '123',
name: 'Example user'
}
})
})
})
})