Easy CRUD backend development with Zod and codehooks-crudlify
Tags: typescript, node, nosql, database
Published: 2023-03-10 11:33:03


Imagine you are building a frontend-app and need a way to persist data. You have a pretty good idea of what the data looks like (the schema). Creating CRUD REST APIs built on top of a database is not super-complex, but still requires a lot of setup and plumbing. This takes time and it’s not fun. What about using services like http://restdb.io and http://airtable.com? That is certainly an option, but what if you need some custom JavaScript code as well? 

[Zod](https://www.npmjs.com/package/zod) and [codehooks-crudlify](https://www.npmjs.com/package/codehooks-crudlify) comes to the rescue!

Zod is a TypeScript-first schema declaration and validation library. Zod is developer friendly and a perfect fit for defining data schemas for REST API CRUD backends.

Crudlify automagically creates a NoSQL backend from any data schema (Zod, Yup, JSON-schema), complete with secure REST APIs, logic middleware and much more. Crudlify is an open source library developed by [codehooks.io](https://codehooks.io).

## Code example
The following code example shows a simple CRUD backend app with a single data schema for `user`. We use Typescript in this example, but JavaScript works just as fine.

```js
// index.ts
import { app } from 'codehooks-js' // Standard Codehooks.io lib
import { crudlify } from 'codehooks-crudlify';
import { z }  from "zod";

const User = z.object({
  username: z.string(),
  email: z.string().email(),
  status: z.boolean().default(true)
}).required({username: true, email: true});

crudlify(app, {user: User})

export default app.init(); // Bind functions to the serverless cloud
```

## Install and deploy

First create a project directory for the source code. 

```bash
mkdir mycrud
cd mycrud
touch index.ts
```
Copy the source code from the example above into the `index.ts` file. 

> Tip: add source code control with `git init`.

Install dependent packages including Zod.

```bash
npm init es6
npm install codehooks -g
npm install codehooks-js codehooks-crudlify zod
```

Then install the [Codehooks CLI](https://codehooks.io/docs/cli) for easy deployment to the cloud.

```bash
npm install codehooks -g
```
> You may be required to `sudo` the command for sufficient access rights.

Create a cloud project for your CRUD backend application. The `coho init` command also creates an example `index.js` example file, just remove this file.

```bash
coho init

rm index.js
```

Finally deploy the app to the serverless cloud.
```bash
coho deploy
```

Test the deployed CRUD app endpoint. 
> Tip: Use [Postman](https://www.postman.com/) or [Thunder](https://www.thunderclient.com/) for easy API testing. 

We use curl for this simple test of the CRUD backend REST API. 

## POST a new User
Use the `coho info --examples` command to view your API endpoint address and secure API tokens. For example, in this example the endpoint address is `https://mycrud-0sbn.api.codehooks.io`.

```bash
curl --location --request POST 'https://mycrud-0sbn.api.codehooks.io/dev/user' \
--header 'x-apikey: a75186df-3880-48ba-a9ed-1e98a6d76d8e' \
--header 'Content-Type: application/json' \
--data-raw '{
    "username": "Joe",
    "email": "joe@example.com"   
}'
```

## GET users
After a successfull POST to the REST API we can query the API for data.

```bash
curl --location --request GET 'https://mycrud-0sbn.api.codehooks.io/dev/user?username=Joe' \
--header 'x-apikey: a75186df-3880-48ba-a9ed-1e98a6d76d8e' \
--header 'Content-Type: application/json'
```

Result

```json
[
    {
        "username": "Joe",
        "email": "joe@example.com",
        "status": true,
        "_id": "186caaac119-tiry33nf09dvuj"
    }
]
```

## Testing that Zod validates the data schema

Let's POST a JSON document with an invalid email address and see what happens.

```bash
curl --location --request POST 'https://mycrud-0sbn.api.codehooks.io/dev/user' \
--header 'x-apikey: a75186df-3880-48ba-a9ed-1e98a6d76d8e' \
--header 'Content-Type: application/json' \
--data-raw '{
    "username": "Jane",
    "email": "jane.example.com"   
}'
```

Result from Zod shows that it's working as expected.

```json
[
    {
        "validation": "email",
        "code": "invalid_string",
        "message": "Invalid email",
        "path": [
            "email"
        ]
    }
]
```

## Conclusion

Validation libraries are useful for more than just validation. They are schemas, and as such they can describe a REST CRUD API - something "codehooks-crudlify" have shown us. If you are eager to get this set up but want to run it locally, you can use a regular Node.js Express server and a MongoDB database with the NPM package [codehooks-mongodb](https://www.npmjs.com/package/codehooks-mongodb).

Happy coding!