Giter Club home page Giter Club logo

next-joi's Introduction

next-joi

Validate NEXT.js API Routes with joi ๐Ÿ˜„

github action badge

Install

yarn add next-joi

This package does not bundle with next.js or joi, so you will need to install them separately.

Getting started

How does it work?

The validation function will check the incoming request against the defined validation schemas. If the request does not comply with the schemas, it will be aborted immediately, and (by default) a 400 BAD REQUEST response will be returned. It is possible to customize this error handling by passing a custom onValidationError function to the primary factory function.

lib/middlewares/validation.ts

import withJoi from "next-joi";

export default withJoi({
  onValidationError: (_, res) => {
    res.status(400).end();
  },
});

Working with NEXT.js API Routes

If you are using standard NEXT.js API Routes, you may use the validation function to wrap your route definition and pass along the validation schema:

import Joi from "joi";

import validate from "/lib/middlewares/validation";

const schema = Joi.object({
  birthdate: Joi.date().iso(),
  email: Joi.string().email().required(),
  name: Joi.string().required(),
});

export default validate({ body: schema }, (req, res) => {
  // This function will be only executed if the incoming request complies
  // with the validation schema defined above.
});

NEXT.js & connect-like middlewares

If your routes are powered by using a package such as next-connect, you can still use next-joi! The middleware function is ready to work with connect just out-of-the-box:

import Joi from "joi";
import connect from "next-connect";

import validate from "/lib/middlewares/validation";

const schema = Joi.object({
  birthdate: Joi.date().iso(),
  email: Joi.string().email().required(),
  name: Joi.string().required(),
});

export default connect().post(validate({ body: schema }), (req, res) => {
  // This function will be only executed if the incoming request complies
  // with the validation schema defined above.
}))

API

withJoi(config?) => validate

This factory function may optionally receive a configuration object. It will return the actual validation function (validate) that can be used as API route middleware.

config

Optional

If omitted, next-joi will use a default configuration.

config.onValidationError

Required

Custom error function to handle validation errors. It will receive the API request, response, and validation error.

import withJoi from "next-joi";

export default withJoi({
  onValidationError: (req, res, error) => {
    res.status(400).end();
  },
});

validate(schemas, handler)

The validate function has support to check the following request fields: body, headers and query. The first argument for this function should always be an object with the desired validation schemas.

schemas

Required

Even if empty, this argument is required.

schemas.body

Optional

A valid joi schema.

schemas.headers

Optional

Note: since most of the time, you may receive more headers than expected, it is a good practice to make this schema always support unknown keys. Otherwise, the validation will fail.

A valid joi schema.

schemas.query

Optional

A valid joi schema.

handler

Optional

A valid next API Route handler. If you are using the validate function without a connect-like middleware engine, this argument becomes mandatory.

Example:

const handler = function (req: NextApiRequest, res: NextApiResponse) {
  // implementation
};

export default validate({}, handler);

next-joi's People

Contributors

jackhedaya avatar sergioalvz avatar sualko avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

next-joi's Issues

Typed request

Thanks for this small little, but handy middleware. Great work ๐Ÿ‘

I extended the default request interface to have a strongly typed parameter and thought, maybe this is also useful for others, or maybe it could even be integrated.

import type { NextApiRequest, NextApiResponse } from 'next'

export interface ValidatedApiRequest<Body = any, Query extends NextApiRequest['query'] = NextApiRequest['query']> extends NextApiRequest {
    body: Body
    query: Query
}

const query = Joi.object({
    id: Joi.string().required(),
});

async function handler(
  req: ValidatedApiRequest<undefined, {id: string}>,
  res: NextApiResponse
) {
//...
}

export default validator({query}, handler;

Serious question: Why isn't this more popular?

Hi,

I am just learning how to develop with nextjs and am planning to use API routes. Like with any API, I understand there needs to be some validation.

To my great surprise, I can hardly find any information on how to validate nextjs API routes. I had believed it would be a much more common use case. The closest information is your package, and it has around 300 downloads this week; a number I thought would be higher.

Therefore, I am wondering if you can help me understand how most people validate their nextjs API routes? Also, is the lack of information due to the fact that people aren't using nextjs API routes?

Thank you for any help.

Is Joi.default() supported?

I am trying to add a default value to an optional parameter, but Joi.default() doesn't seem to take effect.
My code looks somehow like this:

const params = Joi.object({
  language: Joi.string().default('en-us')
})

export default validate({ body: params }, async (req, res) => {
  console.log(req.body.language) // outputs undefined if not passed
})

I'm guessing either I shouldn't access body with req.body or this is not supported, is it?
Thanks in advance.

Retrun error Joi

how get error message from joi validation?

`import withJoi from "next-joi";

export default withJoi({
onValidationError: (req, res) => {
return res.status(400).end();
},
});`

Get converted payload after validation

Hello,

I am using next-joi with next-connect and it works great.
I was wondering if there is a way for the request handler to receive the validated/converted payload.

For example:

const schema = Joi.object({
  name: Joi.string().trim(),
  number: Joi.number().integer(),
})

req.body = {
  name: "    dummy  ",
  number: "5",
}

const handler = nextConnect().post( validate({ body: schema }), async (req, res) => {
    const { name, number } = req.body

   // Here name and number are the original values
   // I would like them to be "dummy" and 5 (name trimmed and number casted to int)
  })

Next 10 Support

"next": "^9.5.1"

Hi there! Are there any plans to support Next 10?

Edit: This is a peer dependency issue that comes from NPM 7 changing how peer dependencies work.

Type is not assignable to type 'OnValidationError'

Following the readme exactly, I am getting the following lint error from my lib/middlewares/validation.ts file.

Type '(_: NextApiRequest, res: NextApiResponse<any>) => NextApiResponse<any>' is not assignable to type 'OnValidationError'.
  Type 'NextApiResponse<any>' is not assignable to type 'void | Promise<void>'.
    Type 'ServerResponse & { send: Send<any>; json: Send<any>; status: (statusCode: number) => NextApiResponse<any>; redirect(url: string): NextApiResponse<...>; redirect(status: number, url: string): NextApiResponse<...>; setPreviewData: (data: string | object, options?: { ...; } | undefined) => NextApiResponse<...>; clearPr...' is missing the following properties from type 'Promise<void>': then, catch, finally, [Symbol.toStringTag]ts(2322)

package.json:

    "dependencies": {
        "@prisma/client": "^3.8.1",
        "joi": "^17.5.0",
        "next": "12.0.8",
        "next-joi": "^2.2.1",
        "prisma-client": "^0.0.0",
        "react": "17.0.2",
        "react-dom": "17.0.2"
    },
    "devDependencies": {
        "@types/node": "^17.0.10",
        "@types/react": "17.0.38",
        "eslint": "8.7.0",
        "eslint-config-next": "12.0.8",
        "prisma": "^3.8.1",
        "ts-node": "^10.4.0",
        "typescript": "^4.5.5"
    }

Return error messages

It'd be helpful if

  1. error messages from validation are returned
  2. there is an option to set flag to return error messages
  3. a custom error message is allowed to passed in validate method
    return res.status(400).end();

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.