Skip to content

Instantly share code, notes, and snippets.

@chief-wizard
Created September 6, 2021 07:55
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chief-wizard/c798f3132e444a9ce2a0746d94ae4fa5 to your computer and use it in GitHub Desktop.
Save chief-wizard/c798f3132e444a9ce2a0746d94ae4fa5 to your computer and use it in GitHub Desktop.
An example type-safe API with Node.js, Express.js, Prisma, and Joi that uses MySQL.
/** Required Node.js modules */
const Express = require('express');
const Joi = require('joi')
const joiMiddleware = require('express-joi-validation').createValidator({})
const Prisma = require('prisma/prisma-client');
/** Instantiate Prisma client */
const prisma = new Prisma.PrismaClient();
/** Supplier validation schema for Joi */
const supplierSchema = Joi.object({
id: Joi.number().greater(0),
name: Joi.string().alphanum().min(1).max(191),
contact: Joi.string().alphanum().min(1).max(191),
email: Joi.string().email().max(191),
phone_num: Joi.string().length(10).pattern(/^[0-9]+$/),
address: Joi.string().alphanum().min(1).max(191),
});
/** Initialize Express */
const app = Express();
app.use(Express.json());
const port = 3000;
/** Routes */
app.get('/', (req, res) => {
res.send("Hello, API server!");
});
/** Create a new supplier and write it to MySQL */
app.post("/supplier/create", joiMiddleware.query(supplierSchema), async (req, res) => {
try {
/** Use Prisma to write the data to our MySQL database */
res.body = await prisma.supplier.create({
data: {
name: req.body.name,
contact: req.body.contact,
email: req.body.email,
phone_num: req.body.phone_num,
address: req.body.address,
}
});
/** Send a response telling the user our data has been written */
res.status(200).send({"message": "OK"});
}
/** If Prisma fails to write to the MySQL database */
/** Catch the error and send it as our response */
catch (err) {
res.status(500).send(err);
}
});
/** Get a supplier by name, return the object in our response */
app.get('/supplier', async (req, res) => {
try {
const supplier = await prisma.supplier.findUnique({
where: {
name: req.body.name,
}
});
/** Send the Supplier object as our response */
res.status(200).send({"object": supplier});
}
/** When Prisma fails to read from database, catch the error and send it as our response */
catch (err) {
res.status(500).send(err);
}
});
/** Update an existing supplier */
app.patch("/supplier/update", joiMiddleware.query(supplierSchema), async (req, res) => {
try {
/** Use Prisma to write the data to our MySQL database */
await prisma.supplier.update({
where: {
id: req.body.id,
},
data: {
name: req.body.name,
contact: req.body.contact,
email: req.body.email,
phone_num: req.body.phone_num,
address: req.body.address,
}
});
/** Send a response telling the user our data has been written */
res.status(200).send({"message": "OK"});
}
/** When Prisma fails to write to database, catch the error and send it as response */
catch (err) {
res.status(500).send(err);
}
});
/** Delete a supplier with a given name */
app.delete('/supplier/delete', joiMiddleware.query(supplierSchema), async (req, res) => {
try {
const supplier = await prisma.supplier.delete({
where: {
name: req.body.name,
}
});
res.status(200).send({"message": "deleted OK"});
}
/** If Prisma fails to delete the object, catch the error and send it as response */
catch (err) {
res.status(500).send(err);
}
});
/** Server */
app.listen(port, () => {
console.log(`API listening on localhost: ${port}`);
});
@chief-wizard
Copy link
Author

chief-wizard commented Sep 6, 2021

The prisma/schema.prisma file contents:

datasource db {
  provider = "mysql"
  url      = env("DATABASE_URL")
}

generator client {
  provider = "prisma-client-js"
}

model Supplier {
 id        Int    @id @default(autoincrement())
 name      String @unique
 contact   String
 email     String
 phone_num String
 address   String
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment