Skip to main content

Database CRUD API

A standard deployed Codehooks.io application has a complete and secure REST API for basic database CRUD operations. The CRUD REST API is implemented by bundling the deployed application with the Crudlify API.

When you create a new project a default auto generated application is deployed, this application implements a full database CRUD REST API. The code for this is shown below.

import {app} from 'codehooks-js'
app.crudlify(); // CRUD REST API
export default app.init();

All database URL endpoints are prefixed with the project ID, Codehooks api endpoint, and the database space name. For example, if your project ID is myproject and the database space is dev, then the full URL endpoint for the REST API is: https://myproject-ff00.api.codehooks.io/dev/people?name=Ally.

Database REST API quick overview

API descriptionHTTP verbRoute
Get list of documentsGET/:collection
Get documents by queryGET/:collection?query
Get document by IDGET/:collection/:ID
Create a new documentPOST/:collection
Update a document by IDPATCH/:collection/:ID
Replace a document by IDPUT/:collection/:ID
Delete a document by IDDELETE/:collection/:ID
Update multiple documents by queryPATCH/:collection/:ID/_byquery
Delete multiple documents by queryDELETE/:collection/:ID/_byquery
Database collections

Create and manage collections with the Codehooks CLI command coho createcollection or using the Codehooks Studio [➕ Create collection] menu.

Security

All databases are protected with encrypted HTTPS protocol, secure API tokens or JWT tokens. You can also add IP filters and much more, read more about Authentication here.

API tokens: List your database API tokens with the CLI command coho info. Create new API tokens with the CLI command coho add-token.

Database REST API

Get list of documents

Retrieve all collection data.

URL: /:collection[?options]

Method: GET

Parameters:

  • collection: a valid collection name, e.g. people

Options:

  • limit: limit result, e.g. ?limit=2
  • offset: skip forward in data result set
  • fields: comma separated list of fields to show, e.g. ?limit=2&fields=Last Name,Sex
  • sort: comma separated list of fields to sort result by, e.g. ?limit=2&sort=-Sex,Last Name

Returns Array of JSON documents

Code example

curl 'https://myproject-ff00.api.codehooks.io/dev/people?limit=2' \
-H 'x-apikey: 3c932310-3fab-4ba3-8102-b75ba0f05149'

Success response 200 OK

[
{
"Index": 54901,
"User Id": "d088FCEC6EDEF20",
"First Name": "Michaela",
"Last Name": "Callahan",
"Sex": "Male",
"Email": "[email protected]",
"Phone": "108-950-4850x6836",
"Date of birth": "2010-11-07",
"Job Title": "Research scientist (maths)",
"_id": "64bb88b51ed9a3057ac99d9c"
},
{
"Index": 54902,
"User Id": "40Fd72E5AaC5b67",
"First Name": "Lacey",
"Last Name": "Saunders",
"Sex": "Male",
"Email": "[email protected]",
"Phone": "623.506.2528x932",
"Date of birth": "1946-06-28",
"Job Title": "Insurance claims handler",
"_id": "64bb88b51ed9a3057ac99d9d"
}
]

Error response 401 no access

401 no access

Get documents by query

Retrieve collection data filtered by a query parameter.

URL: /:collection[?query&options]

Method: GET

Parameters:

  • collection: a valid collection name, e.g. people

Query:

  • Simple queries using URL parameters:
    • name=value - e.g. ?First Name=Michaela
  • Advanced MongoDB query using URL JSON:
    • q={...} - e.g. ?q={"First Name"\: {"$regex"\: "en"}, "Last Name"\: {"$in"\: ["Saunders", "Massey"]}}

Options:

  • limit: limit result, e.g. ?limit=2
  • offset: skip forward in data result set
  • fields: comma separated list of fields to show, e.g. ?limit=2&fields=Last Name,Sex
  • sort: comma separated list of fields to sort result by, e.g. ?limit=2&sort=-Sex,Last Name

Returns Array of JSON documents

Code example: simple query

curl --location 'https://myproject-ff00.api.codehooks.io/dev/people?First%20Name=Michaela&fields=First%20Name%2CEmail%2C_id' \
--header 'x-apikey: 3c932310-3fab-4ba3-8102-b75ba0f05149'

Success response 200 OK

[
{
"First Name": "Michaela",
"Email": "[email protected]",
"_id": "64bb88b51ed9a3057ac99d9c"
}
]

Code example: advanced query

URL encoding

Notice that advanced query parameter q={...} should be programmatically URL encoded before sent to the server. E.g. the query:

{"First Name":{"$regex":"en"},"Last Name":{"$in":["Saunders","Massey"]}}

when URL encoded equals:

{%22First%20Name%22%3A{%22%24regex%22%3A%22en%22}%2C%22Last%20Name%22%3A{%22%24in%22%3A[%22Saunders%22%2C%22Massey%22]}}
curl --location --globoff 'http://alf1-o5gi.api.codehooks.local.io/dev/people?q={%22First%20Name%22%3A{%22%24regex%22%3A%22en%22}%2C%22Last%20Name%22%3A{%22%24in%22%3A[%22Saunders%22%2C%22Massey%22]}}' \
--header 'x-apikey: 3c932310-3fab-4ba3-8102-b75ba0f05149'

Success response 200 OK

[
{
"Index": 54907,
"User Id": "18E57F5a6aaC1ab",
"First Name": "Darlene",
"Last Name": "Saunders",
"Sex": "Female",
"Email": "[email protected]",
"Phone": "001-158-700-3226",
"Date of birth": "1970-08-23",
"Job Title": "Scientist, forensic",
"_id": "64bb88b51ed9a3057ac99da2"
},
{
"Index": 54933,
"User Id": "aeD915eA429Fb02",
"First Name": "Lauren",
"Last Name": "Massey",
"Sex": "Male",
"Email": "[email protected]",
"Phone": "+1-716-581-5746x2442",
"Date of birth": "2001-10-21",
"Job Title": "Information systems manager",
"_id": "64bb88b51ed9a3057ac99dbc"
}
]

Error response 401 no access

401 no access

Error response 400 Bad Request

Unexpected token } in JSON at position 5

Get document by ID

Retrieve a document from a collection.

URL: /:collection/:ID

Method: GET

Parameters:

  • collection: a valid collection name, e.g. people
  • ID: an existing document _id value

Returns A JSON document

Code example

curl --location 'https://myproject-ff00.api.codehooks.io/dev/people/64bb88b51ed9a3057ac99d9c' \
--header 'x-apikey: 3c932310-3fab-4ba3-8102-b75ba0f05149'

Success response 200 OK

{
"Index": 54901,
"User Id": "d088FCEC6EDEF20",
"First Name": "Michaela",
"Last Name": "Callahan",
"Sex": "Male",
"Email": "[email protected]",
"Phone": "108-950-4850x6836",
"Date of birth": "2010-11-07",
"Job Title": "Research scientist (maths)",
"_id": "64bb88b51ed9a3057ac99d9c"
}

Error response 401 no access

401 no access

Error response 404 Not Found

3 INVALID_ARGUMENT: NotFoundError: Key not found in database [64bb88b51ed9a3057ac99d9cc]

Create a new document

Insert a new JSON document in a collection.

URL: /:collection

Method: POST

Parameters:

  • collection: a valid collection name, e.g. people
  • body: a valid JSON document

Returns The created JSON document

Code example

curl --location 'https://myproject-ff00.api.codehooks.io/dev/people' \
--header 'x-apikey: 3c932310-3fab-4ba3-8102-b75ba0f05149' \
--header 'Content-Type: application/json' \
--data-raw '{
"First Name": "Jim",
"Last Name": "Callahan",
"Email": "[email protected]",
"Phone": "108-950-4850x6836",
"Date of birth": "1995-11-07",
"Job Title": "Software tester"
}'

Success response 201 Created

{
"First Name": "Jim",
"Last Name": "Callahan",
"Email": "[email protected]",
"Phone": "108-950-4850x6836",
"Date of birth": "1995-11-07",
"Job Title": "Software tester",
"_id": "64bbc861f13609074a5d981a"
}

Error response 401 no access

401 no access

Error response 400 Bad Request

E.g. error when POST an invalid JSON document.

SyntaxError: Unexpected token S in JSON at position 174

Or an validator error message when using a Yup validator.

{
"name": "ValidationError",
"message": "age is a required field"
}

Update a document by ID

Update a JSON document in a collection.

URL: /:collection/:ID

Method: PATCH

Parameters:

  • collection: a valid collection name, e.g. people
  • ID: a valid document _id
  • body: a valid JSON document

Returns The updated JSON document

Code example

curl --location --request PATCH 'https://myproject-ff00.api.codehooks.io/dev/people/64bbc861f13609074a5d981a' \
--header 'x-apikey: 3c932310-3fab-4ba3-8102-b75ba0f05149' \
--header 'Content-Type: application/json' \
--data '{
"Phone": "123-345-12332x6836",
"Job Title": "Bug master"
}'

Success response 200 OK

{
"First Name": "Jim",
"Last Name": "Callahan",
"Email": "[email protected]",
"Phone": "123-345-12332x6836",
"Date of birth": "1995-11-07",
"Job Title": "Bug master",
"_id": "64bbc861f13609074a5d981a"
}

Error response 401 no access

401 no access

Error response 400 Bad Request

E.g. invalid JSON document.

Bad request

Replace a document by ID

Replace a JSON document in a collection.

URL: /:collection/:ID

Method: PUT

Parameters:

  • collection: a valid collection name, e.g. people
  • ID: a valid document _id
  • body: a valid JSON document

Returns The replaced JSON document

Code example

curl --location --request PUT 'https://myproject-ff00.api.codehooks.io/dev/people/64bbc861f13609074a5d981a' \
--header 'x-apikey: 3c932310-3fab-4ba3-8102-b75ba0f05149' \
--header 'Content-Type: application/json' \
--data '{
"First Name": "Re",
"Last Name": "Placed",
"Job Title": "Replacer"
}'

Success response 200 OK

{
"First Name": "Re",
"Last Name": "Placed",
"Job Title": "Replacer",
"_id": "64bbc861f13609074a5d981a"
}

Error response 401 no access

401 no access

Error response 400 Bad Request

E.g. invalid JSON document using a Yup validator.

{
"name": "ValidationError",
"message": "age is a required field"
}

Delete a document by ID

Delete a JSON document in a collection.

URL: /:collection/:ID

Method: DELETE

Parameters:

  • collection: a valid collection name, e.g. people
  • ID: a valid document _id

Returns The deleted document _id

Code example

curl --location --request DELETE 'https://myproject-ff00.api.codehooks.io/dev/people/64bbc861f13609074a5d981a' \
--header 'x-apikey: 3c932310-3fab-4ba3-8102-b75ba0f05149'

Success response 200 OK

{
"_id": "64bbc861f13609074a5d981a"
}

Error response 401 no access

401 no access

Update multiple documents by query

Update multiple JSON document by query in a collection.

URL: /:collection/_byquery[?query&options]

Method: PATCH

Parameters:

  • collection: a valid collection name, e.g. people
  • body: a valid JSON document to update on all matches

Query:

  • Simple queries using URL parameters:
    • name=value - e.g. ?First Name=Michaela
  • Advanced MongoDB query using URL JSON:
    • q={...} - e.g. ?q={"First Name": {"$regex": "en"}, "Last Name": {"$in": ["Saunders", "Massey"]}}

Returns Count of updated documents

Code example

curl --location --request PATCH 'https://myproject-ff00.api.codehooks.io/dev/people/_byquery?Job%20Title=%22Scientist%2C%20forensic%22' \
--header 'x-apikey: 3c932310-3fab-4ba3-8102-b75ba0f05149' \
--header 'Content-Type: application/json' \
--data '{
"$set": {
"salary": "high"
},
"$inc": {
"visited": 1
}
}'

Success response 200 OK

{
"count": 2
}

Error response 401 no access

401 no access

Error response 400 Bad Request

Bad Request

Delete multiple documents by query

Delete multiple JSON document by query in a collection.

Erases all matched documents by query

Please ensure that the applied query is correct. An empty query parameter will erase all documents in collection.

URL: /:collection/_byquery[?query&options]

Method: DELETE

Parameters:

  • collection: a valid collection name, e.g. people

Query:

  • Simple queries using URL parameters:
    • name=value - e.g. ?First Name=Michaela
  • Advanced MongoDB query using URL JSON:
    • q={...} - e.g. ?q={"First Name": {"$regex": "en"}, "Last Name": {"$in": ["Saunders", "Massey"]}}

Returns Count of deleted documents

Code example

curl --location --request DELETE 'http://myproject-ff00.api.codehooks.io/dev/people/_byquery?Job%20Title=%22Scientist%2C%20forensic%22' \
--header 'x-apikey: 3c932310-3fab-4ba3-8102-b75ba0f05149'

Success response 200 OK

{
"count": 2
}

Error response 401 no access

401 no access

Data Schema support

Codehooks 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.

Data validation with Yup

The code example below shows how easy it is to validate data with a Yup data schema.

Run npm i yup in project folder.

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

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

app.crudlify({user: userSchema})

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

Data validation with JSON-schema

The next code example uses JSON-schema to validate data.

Run npm i z-schema in project folder.

import {app} from 'codehooks-js'
import ZSchema from 'z-schema';

const userSchema = {
id: "personDetails",
type: "object",
properties: {
firstName: { type: "string" },
lastName: { type: "string" }
},
required: ["firstName", "lastName"]
}

app.crudlify({user: userSchema});

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

Data validation with Zod

Zod is another popular data validation library.

Run npm i zod in project folder.

A simple code example using Zod is show below.

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

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

app.crudlify({user: userSchema})

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

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 are shown in the code example below.

... // collapsed code

app.crudlify({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(`BAD 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)
})
})

... // collapsed code

Examples

Insert a new user to the database

POST a new user using curl.

curl -X POST \
'https://myproject-fef0.api.codehooks.io/dev/user' \
--header 'Content-Type: application/json' \
--data-raw '{
"name": "Ally",
"email": "[email protected]"
}'

Validate data against a Yup data schema

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

curl -X POST \
'https://myproject-fef0.api.codehooks.io/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 \
'https://myproject-fef0.api.codehooks.io/dev/user?name=Ally' \
--header 'Content-Type: application/json'

Example output.

[
{
"_id": "63fb97825f624f479034eb08",
"active": true,
"email": "[email protected]",
"name": "Ally"
}
]

Update a record in the database

curl -X PATCH \
'https://myproject-fef0.api.codehooks.io/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:

https://myproject-fef0.api.codehooks.io/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 parameters:

https://myproject-fef0.api.codehooks.io/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.