1.0.11 • Published 7 months ago

codehooks-crudlify v1.0.11

Weekly downloads
-
License
MIT
Repository
github
Last release
7 months ago

Codehooks-crudlify

Easy database REST API CRUD automation for Node.js. Use this open source package for easy creation of REST APIs and persistent storage for backend applications. This package requires use of codehooks-js together with a codehooks.io backend or using Express/MongoDB with the open source codehooks-mongodb library.

Data and validation schemas

Codehooks-crudlify supports these popular data and validation schemas:

  • Yup - Dead simple Object schema validation
  • Zod - TypeScript-first schema validation with static type inference
  • JSON.schema - Standard declarative language that allows you to annotate and validate JSON documents

Install

Create a new directory for your project. Then initialize with npm and JavaScript ES6.

npm init es6

Install dependent packages.

npm install codehooks-crudlify codehooks-js yup

Usage

Create a Node.js Codehooks backend app like the example shown below. This example uses Yup as data schema.

// index.js
import app from 'codehooks-js';
import { object, string, number, date } from 'yup';
import crudlify from 'codehooks-crudlify';

// database schema
const userSchemaYup = object({
    name: string().required(),
    age: number().required().positive().integer(),
    email: string().email(),
    website: string().url().nullable(),
    createdOn: date().default(() => new Date()),
});

const options = {
    // schema: "yup" (default)
    // schema: "json-schema"
    // schema: "zod"
}

// Make REST API CRUD operations for user collection with Yup schema
crudlify(app, {user: userSchemaYup}, options)

export default app.init(); // export app to a runtime server engine

Deploy application to the codehooks.io cloud service

Using the Codehooks CLI you can deploy the app to with the coho deploy command.

Tip: Inspect the app output using the coho logs -f command.

Alternatively run and manage it yourself with Express and mongoDB, this is shown in the next section.

Run application with Express server and MongoDB

In case you wish to develop and host the application yourself, just follow the recipe explained in this section.

You need to add one extra file, e.g. standalone.js. The code in this file will provide a separate runtime server for the app shown above (the index.js file).

Install the codehooks-mongodb and the other necessary packages to support Express and MongoDB. Also make sure that your app is set up to use the required JavaScript ES6, either by running npm init es6 or by adding "type": "module" in the package.json file.

npm install codehooks-mongo express body-parser

// standalone.js
import coho from './index.js'; // import the codehooks app scope
import mongoStore from 'codehooks-mongodb';
import express from 'express';
import bodyParser from 'body-parser';
const app = express();

// add any necessary express configuration you like
app.use(bodyParser.json({ limit: '10mb' }));

const options = {
    // replace this with the mondoDB connection string you like
    "datastore": new mongoStore('mongodb://localhost:27017') 
}

// Important, make codehooks use express and MongoDB
coho.useExpress(app, options);

// Start the server
app.listen(3000, () => {
    console.log("Running standalone on port 3000")
})

Start the server with node standalone.js and you should see this message in the console.

$ node standalone.js

Running standalone on port 3000

Automatic REST API

By using the crudlify(app, schema) function, your Codehooks.io app effectively gets a complete HTTP CRUD REST API with schema validation and data persistence for your application collections.

Crudlify will create the following REST API endpoints for any collection defined in your schema:

VerbCodehooks.io routeDescription
GEThttps://{TENANT-ID}/{SPACE}/:collectionRetrieve all objects (filtered by query)
GEThttps://{TENANT-ID}/{SPACE}/:collection/:IDRetrieve object by ID
POSThttps://{TENANT-ID}/{SPACE}/:collectionAdd object
PUThttps://{TENANT-ID}/{SPACE}/:collection/:IDReplace object by ID
PATCHhttps://{TENANT-ID}/{SPACE}/:collection/:IDUpdate object by ID
PATCHhttps://{TENANT-ID}/{SPACE}/:collection/_byqueryUpdate object(s) by query
DELETEhttps://{TENANT-ID}/{SPACE}/:collection/:IDDelete object by ID
DELETEhttps://{TENANT-ID}/{SPACE}/:collection/_byqueryDelete object(s) by query

TENANT-ID and SPACE for a Codehooks app is represented with the application endpoint URL.

For example:

https://myapp-xxff.api.codehooks.io/dev/user

Or if you run the application locally use,

http://localhost:3000/dev/user

Examples

Insert a new user to the database

POST a new user using curl.

curl -X POST \
  'http://localhost:3000/dev/user' \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "name": "Ally",
  "email": "ally@example.com"
}'

Validate data against a Yup data schema

Check that the data schema validates correctly by sending an invalid email address.

curl -X POST \
  'http://localhost:3000/dev/user' \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "name": "Sally",
  "email": "sally.example.com"
}'

Validation error shows that Yup works.

400 Bad Request

{
  "value": {
    "active": true,
    "email": "sally.example.com",
    "name": "Sally"
  },
  "path": "email",
  "type": "email",
  "errors": [
    "email must be a valid email"
  ],
  ... # chopped error message
}

Run a query against the database

curl -X GET \
  'http://localhost:3000/dev/user?name=Ally' \
  --header 'Content-Type: application/json' 

Example output.

[
  {
    "_id": "63fb97825f624f479034eb08",
    "active": true,
    "email": "ally@example.com",
    "name": "Ally"
  }
]

Update a record in the database

curl -X PATCH \
  'http://localhost:3000/dev/user/63fb97825f624f479034eb08' \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "name": "Ally Mc. Beal"
}'

Querying the database

You can query the database REST API in two different ways.

Simple to use and quick queries with the URL query language:

http://localhost:3000/dev/user?name=jane&age>23&limit=2&offset=5&sort=email&fields=name,age

Which actually produces this query object:

{ name: 'Jane', age: { '$gt': 23 } }, {
  fields: { name: 1, age: 1 },
  sort: { email: 1 },
  skip: 5,
  limit: 2,
  projection: { name: 1, age: 1 }
}

For advanced use, and programmatic approact, pass inn the full JSON query and hints as URL objects:

http://localhost:3000/dev/user?q={"name": "Jane", "age": {"$gt": 23}}&h={"fields": { "name": 1, "age": 1 },"sort": {"email": 1 },"skip": 5,"limit": 2,"projection": { "name": 1, "age": 1 }}

The last option would probably use JSON.stringify(query) etc. to produce a valid query in the URL.

Database event hooks middleware

To provide additional CRUD logic, events are triggered before and after a database operation.

hooks.before<VERB>(<COLLECTION>, handlerFunction)

hooks.after<VERB>(<COLLECTION>, handlerFunction)

Example event hooks is shown in the code example below.

...
const options = {
    schema: "json-schema"
}

crudlify(app, {user: userSchemaYup}, options).then((hooks) => {

  hooks.beforePOST('user', async (data) => {
      console.log("User data before saving", data)

      // abort operation with a throw, cases 404 status code
      // E.g. throw new Error(`BAAD post for ${data}`)

      // mutate data before saved to the database
      data.foo = 'Was here!'
  })
  hooks.afterPOST('user', async (data) => {
      console.log("User data after saved to the database", data)
  })

...

Options

To use json-schema instead of yup initialize crudlify with the schema option.

crudlify(app, {user: userSchemaJSON}, {schema: "json-schema"})

Quick start

For a quick start you can create an app without any schema or validation. This effectively gives you a CRUD REST API for any collection. The example below shows a bare bone example backend application.

// index.js
import app from 'codehooks-js';
import crudlify from 'codehooks-crudlify';

// Make REST API CRUD operations for any collection no schema
crudlify(app)

export default app.init(); // export app to serverless runtime

Deploy with coho deploy or to Express locally like shown in the examples above.

Documentation

1.0.9

10 months ago

1.0.11

7 months ago

1.0.10

10 months ago

1.0.8

1 year ago

1.0.7

1 year ago

1.0.6

1 year ago

1.0.5

1 year ago

1.0.4

1 year ago

1.0.3

1 year ago

1.0.2

1 year ago

1.0.1

1 year ago