Last active
May 5, 2020 05:53
-
-
Save Sowed/246614abb27f71f668b6e9a314ae6acd to your computer and use it in GitHub Desktop.
Migrating from Custom Express Server with `express-validator` to Next API Routes
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import express, { Request, Response, NextFunction } from 'express'; | |
import { check, validationResult, ValidationChain } from 'express-validator'; | |
import bodyParser from 'body-parser'; | |
import next from 'next'; | |
const postMail = async (req: Request, res: Response): Promise<void> => { | |
// Use nodemailer to post the email. Setup mailer() with nodemailer | |
// and call it to Post an Email and return response | |
const mailResponse = await mailer(req.body); | |
res.json(mailResponse); | |
}; | |
const postValidationRules = (): ValidationChain[] => { | |
return [check('email').isEmail(), check('message').escape()]; | |
}; | |
const validate = ( | |
req: Request, | |
res: Response, | |
nextFn: NextFunction | |
): Response<string> | void => { | |
const errors = validationResult(req); | |
if (errors.isEmpty()) { | |
return nextFn(); | |
} | |
return res.status(422).json({ | |
errors, | |
}); | |
}; | |
const port = parseInt(process.env.PORT || '3000', 10); | |
const clientUrl = process.env.CLIENT_URL || 'http://localhost'; | |
const dev = process.env.NODE_ENV !== 'production'; | |
const app = next({ dev }); | |
const handle = app.getRequestHandler(); | |
(async (): Promise<void> => { | |
try { | |
await app.prepare().then(() => { | |
const server = express(); | |
server.use(bodyParser.json()); | |
server.use(bodyParser.urlencoded({ extended: true })); | |
server.post( | |
'/api/post-contact-form', | |
postValidationRules(), | |
validate, | |
postMail | |
); | |
server.get('*', (req: Request, res: Response) => { | |
return handle(req, res); | |
}); | |
server.post('*', (req: Request, res: Response) => { | |
return handle(req, res); | |
}); | |
server.listen(port, (error: Error) => { | |
if (error) throw error; | |
console.info(`> ✔ Ready on Server: ${clientUrl}:${port}`); | |
}); | |
}); | |
} catch (error) { | |
console.error(`❌ Error`, error); | |
process.exit(1); | |
} | |
})(); |
I have created a repro and you can test it out here.
I left some inline-comments based on your previous recommendations and removed the input fields for brevity, created two separate form data formats for comparison, expecting the invalid
one to fail. However both pass and return the final should be sanitized and emailed data.
I am currently looking into running the validation in an imperative way using run()
but the approach is too repetitive.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
If you prefer to returns all the error in your
resolvedPromises
:resolvedPromises
should contain all the errors.