Database API
The Database API provides a powerful and flexible interface for interacting with the built-in NoSQL datastore in your Codehooks project. This API allows you to perform a wide range of operations, from basic CRUD (Create, Read, Update, Delete) to more advanced querying and data manipulation.
Key Features
- NoSQL Flexibility: Work with schema-less data structures for maximum adaptability.
- CRUD Operations: Easily insert, retrieve, update, and delete documents.
- Advanced Querying: Use MongoDB-style query language for complex data retrieval.
- Data Streaming: Efficiently handle large datasets with streaming capabilities.
- Schema Validation: Optionally enforce data structure with JSON Schema.
- Collection Management: Programmatically create and manage database collections.
Getting Started
To use the Database API, you'll first need to open a connection to the datastore:
import { Datastore } from 'codehooks-js'
async function myDatabaseFunction() {
const conn = await Datastore.open();
// Use conn to interact with the database
// ...
}
Once you have a connection, you can use various methods to interact with your data. Here's a quick overview of some common operations:
insertOne()
: Add a new document to a collectiongetOne()
: Retrieve a single document by ID or querygetMany()
: Retrieve multiple documents matching a queryupdateOne()
: Modify a single documentremoveOne()
: Delete a single document
For more detailed information on each method and advanced usage, refer to the specific sections below.
API quick overview
- Key Features
- Getting Started
- Datastore.open()
- insertOne(collection, document)
- getOne(collection, ID | Query)
- findOne(collection, ID | Query)
- find(collection, query, options)
- getMany(collection, query, options)
- toArray(collection, query, options)
- updateOne(collection, ID | Query, updateoperators, options)
- updateMany(collection, query, document, options)
- replaceOne(collection, ID | Query, document, options)
- replaceMany(collection, query, document, options)
- removeOne(collection, ID | Query)
- removeMany(collection, query, options)
- Data validation
- Collection Management
Datastore.open()
Datastore.open() opens a connection to a datastore in the active project space.
import {Datastore} from 'codehooks-js'
async function myfunc() {
const conn = await Datastore.open();
// use conn to call API functions
...
}
Returns Promise / Datastore connection
insertOne(collection, document)
Insert a new data object into a collection in a datastore.
Parameters
- collection: collection name
- document: JSON document or array of JSON documents
Returns: Promise with the new JSON document and an unique _id
value.
Validation exceptions: See JSON-schema validation
Code example
import {app, Datastore} from 'codehooks-js'
async function createSale(req, res) {
const conn = await Datastore.open();
try {
const doc = await conn.insertOne('sales', req.body);
// return new document to client
res.status(201).json(doc);
} catch (error) {
if (error.schemaError) {
// JSON-schema validation error
res.status(400).json(error);
} else {
// unknown error
res.status(500).json({error: error.message})
}
}
}
// Serverless route hook
app.post('/sales', createSale);
export default app.init(); // Bind functions to the serverless runtime
Example input and result
POST
https://myproject-ff00.api.codehooks.io/dev/sales
Example input:
{
"Region": "North America",
"Item Type": "Cereal",
"Volume": 200
}
Example output:
{
"_id": "640f60e2b4fdc00015c4280f",
"Region": "North America",
"Item Type": "Cereal",
"Volume": 200
}
getOne(collection, ID | Query)
Get one data object by ID or by Query from a collection in a datastore.
Parameters
- collection: name of collection
- ID or Query: the
_id
value, or a Query{value: "some value"}
Returns Promise with json document
Code example
import {app, Datastore} from 'codehooks-js'
async function getOne(req, res) {
try {
const conn = await Datastore.open();
const {id} = req.params;
const data = await conn.getOne('customer', id); // same as conn.getOne('customer', {_id: id})
res.json(data)
} catch (error) {
// not found
res.status(404).json({error: error.message})
}
}
// Serverless route hook
app.get('/cust/:id', getOne);
export default app.init(); // Bind functions to the serverless runtime
Example input and result
GET
https://myproject-ff00.api.codehooks.io/dev/cust/640f60f2b4fdc00015c42811
Example output:
{
"name": "Acme Inc.",
_id: "640f60f2b4fdc00015c42811"
}
findOne(collection, ID | Query)
Alias for getOne
find(collection, query, options)
Alias for getMany
getMany(collection, query, options)
Stream multiple data objects from a collection in a datastore.
Data are sorted naturally by the index for the collection, default index is by _id
which will stream data in chronological order.
Parameters
- collection: collection name (mandatory)
- query: mongoDB query object, e.g.
{name: "Jane"}
(Read query language docs). Default query is empty{}
, i.e. all objects - options (optional settings)
- sort: mongoDB sort object. E.g. sort by name ascending
{"name": 1}
- limit: how many items to return
- hints: include or omit fields
- Include fields example:
{$fields: {name: 1, address: 1}}
- Omit fields example:
{$fields: {name: 0, _id_: 0}}
- Include fields example:
- offset: how many items to skip before returning any
- sort: mongoDB sort object. E.g. sort by name ascending
Returns a JSON array data stream.
Simple code example
import {app, Datastore} from 'codehooks-js'
async function getSales(req, res) {
const conn = await Datastore.open();
conn.getMany('sales').json(res); // pipe json stream to client
}
// Serverless route hook
app.get('/sales', getSales);
export default app.init(); // Bind functions to the serverless runtime
Example input and result
GET
https://myproject-ff00.api.codehooks.io/dev/sales
Example output:
[
{
"Region": "France",
"Item Type": "Veal",
"Volume": 130,
"Unit Price": 2005.7,
"Unit Cost": 11s7.11,
"_id": "640f60e2b4fdc00015c4280f"
},
{
"Region": "Germany",
"Item Type": "Haxe",
"Volume": 30,
"Unit Price": 30.4,
"Unit Cost": 32.43,
"_id": "640f60e2b4fdc00015c4282f"
}
]
Advanced code example
import {app, Datastore} from 'codehooks-js'
async function getSales(req, res) {
const conn = await Datastore.open();
const query = {"Volume": {$gt: req.params.vol}};
const options = {
limit: 1000,
hints: {$fields: {status: 0, _id: 0}}
}
conn.getMany('sales', query, options).json(res); // json stream is piped back to client
}
// Serverless route hook
app.get('/sales/:vol', getSales);
export default app.init(); // Bind functions to the serverless runtime
Example input and result
GET
https://myproject-ff00.api.codehooks.io/dev/sales/1000
Example output:
[
{
"Region": "North America",
"Item Type": "Cereal",
"Volume": 1304,
"Unit Price": 205.7,
"Unit Cost": 117.11
},
{
"Region": "North America",
"Item Type": "Cereal",
"Volume": 1306,
"Unit Price": 10.3,
"Unit Cost": 3.3
}
]
Streaming data code example
With the steaming API you're in full control over how to deliver data back to a client.
In this example the content-type
is set first, next the code is using forEach
to iterate the stream to output one line of data per database object.
import {app, Datastore} from 'codehooks-js'
async function getSales(req, res) {
res.set('content-type', 'text/plain')
const conn = await Datastore.open();
let count = 0;
const cursor = conn.getMany('sales', {"Item Type": "Cereal"})
await cursor.forEach((item) => {
// use the response.write to stream data back to client
res.write(`Item ${count++} has volume ${item.Volume}\n`)
})
res.end()
}
// Serverless route hook
app.get('/sales', getSales);
export default app.init(); // Bind functions to the serverless runtime
Output from the streaming data code example:
Item 0 has volume 1304
Item 1 has volume 1306
...
toArray(collection, query, options)
Utility function to return multiple data objects as an array of objects from the getMany API call.
Simple code example
import {app, Datastore} from 'codehooks-js'
async function getSales(req, res) {
const conn = await Datastore.open();
const query = {"product": "foo"}; // query for foo products
const array = await conn.getMany('sales', query).toArray(); // as array
// return json array
res.json(array);
}
// Serverless route hook
app.get('/sales', getSales);
export default app.init(); // Bind functions to the serverless runtime
updateOne(collection, ID | Query, updateoperators, options)
Update one data object by ID or by Query in a datastore collection. Input document is patched with the matched database object.
Parameters
- collection: name of collection
- ID or Query: the
_id
value, or a Query{value: "some value"}
- updateoperators: new json document to update or manipulate data operators
- options: (optional settings)
- upsert: Create a new document if ID does not exist by
{upsert: true}
- upsert: Create a new document if ID does not exist by
Returns: Promise with updated json document
Validation exceptions: See JSON-schema validation
Code example: update by ID
import {app, Datastore} from 'codehooks-js'
async function myFunc(req, res) {
const {id} = req.params;
const {body} = req;
const conn = await Datastore.open();
const data = await conn.updateOne('customer', {_id: id}, {$set: body});
res.json(data);
}
// Serverless route hook
app.put('/cust/:id', myFunc);
export default app.init(); // Bind functions to the serverless runtime
Example input and result
POST
https://myproject-ff00.api.codehooks.io/dev/cust/640f60f2b4fdc00015c42811
Example input:
{
"name": "Acme Inc.",
"sales": 42
}
Code example: update using the upsert option
// upsert api route
app.post('/update', async (req, res) => {
const {email} = req.body;
console.log('upsert', email)
const conn = await datastore.open()
const upsertResult = await conn.updateOne('users',
// query
{
"emailAddress": email
},
// update operators
{
$set: { "emailAddress": email },
$inc: { "visits": 1 }
},
// upsert option
{upsert: true})
res.json(upsertResult)
})
Example input and result
POST
https://myproject-ff00.api.codehooks.io/dev/update
# example input:
{
"email": "[email protected]"
}
# example output:
{
"emailAddress": "[email protected]",
"visits": 8,
"_id": "658af419d44110bef4e88beb"
}
updateMany(collection, query, document, options)
Update multiple data objects in a datastore collection. Input document is patched with the matched database objects.
Parameters
- collection: name of collection
- query: mongoDB query object (docs)
- document: new json document to update or manipulate
- options (optional settings)
Returns: Promise with count of objects updated
Validation exceptions: See JSON-schema validation
Code example
import {app, Datastore} from 'codehooks-js'
async function myFunc(req, res) {
const conn = await Datastore.open();
const query = {
"customerStatus": "GOLD"
}
const doc = {
$inc: {"bonus": "20"},
$set: {customerStatus: "PLATINUM"}
};
const data = await conn.updateMany('customer', query, doc);
res.json(data);
}
// Serverless route hook
app.put('/cust', myFunc);
export default app.init(); // Bind functions to the serverless runtime
Example input and result
PUT
https://myproject-ff00.api.codehooks.io/dev/cust
Example output:
[
{
"name": "Acme Inc.",
"customerStatus": "PLATINUM",
"bonus": "20",
_id: "640f60f2b4fdc00015c42811"
},
{
"name": "Colo Inc.",
"customerStatus": "PLATINUM",
"bonus": "30",
_id: "640f60f2b4fdc00015c42f00"
},
...
]
replaceOne(collection, ID | Query, document, options)
Replace one data object by ID or by Query in a datastore collection.
Input document overwrites the matched database object, the _id
value is not overwritten.
Parameters
- collection: name of collection
- ID or Query: the
_id
value, or a Query{value: "some value"}
- document: new json document to replace
- options: (optional settings)
- upsert: Create a new document if ID does not exist by
{upsert: true}
- upsert: Create a new document if ID does not exist by
Returns Promise with updated json document
Validation exceptions: See JSON-schema validation
Code example
import {app, Datastore} from 'codehooks-js'
async function myFunc(req, res) {
const conn = await Datastore.open();
const data = await conn.replaceOne('customer', {_id: req.params.id}, req.body);
res.json(data);
}
// Serverless route hook
app.put('/cust/:id', myFunc);
export default app.init(); // Bind functions to the serverless runtime
Example input and result
POST
https://myproject-ff00.api.codehooks.io/dev/cust/640f60f2b4fdc00015c42811
Example input:
{
"name": "Acme Replacement Inc.",
"sales": 0
}
replaceMany(collection, query, document, options)
Replace multiple data objects in a datastore collection.
Input document overwrites the matched database objects. The _id
value is not overwritten.
Parameters
- collection: name of collection
- query: mongoDB query object (docs)
- document: new json document to replace
- options (optional settings)
Returns Promise with count of objects updated
Validation exceptions: See JSON-schema validation
Code example
import {app, Datastore} from 'codehooks-js'
async function myFunc(req, res) {
const conn = await Datastore.open();
const query = {
"customerStatus": "GOLD"
}
const doc = {
"Acme": "was here"
};
const data = await conn.replaceMany('customer', query, doc);
res.json(data);
}
// Serverless route hook
app.put('/cust', myFunc);
export default app.init(); // Bind functions to the serverless runtime
Example input and result
PUT
https://myproject-ff00.api.codehooks.io/dev/cust
Example output:
[
{
"Acme": "was here"
_id: "640f60f2b4fdc00015c42811"
},
{
"Acme": "was here"
_id: "640f60f2b4fdc00015c400fe"
},
...
]
removeOne(collection, ID | Query)
Remove one data object by ID or by Query in a datastore collection.
Parameters
- collection: name of collection
- ID or Query: the
_id
value, or a Query{value: "some value"}
Returns Promise with document ID
Code example
import {app, Datastore} from 'codehooks-js'
async function myFunc(req, res) {
const conn = await Datastore.open();
const data = await conn.removeOne('customer', {_id: req.params.id});
res.json(data);
}
// Serverless route hook
app.delete('/cust/:id', myFunc);
export default app.init(); // Bind functions to the serverless runtime
Example input and result
DELETE
https://myproject-ff00.api.codehooks.io/dev/cust/640f60f2b4fdc00015c42811
Example output:
640f60f2b4fdc00015c42811
removeMany(collection, query, options)
Remove multiple data objects in a datastore collection.
Parameters
- collection: name of collection
- query: mongoDB query object (docs)
- options (optional settings)
Returns Promise with count of objects deleted
Code example
import {app, Datastore} from 'codehooks-js'
async function myFunc(req, res) {
const conn = await Datastore.open();
const query = {
"customerStatus": "GOLD"
}
const data = await conn.removeMany('customer', query);
res.json(data);
}
// Serverless route hook
app.delete('/cust', myFunc);
export default app.init(); // Bind functions to the serverless runtime
Example input and result
DELETE
https://myproject-ff00.api.codehooks.io/dev/cust
Example output:
{"count": 3}
Data validation
Add data validation (JSON-schema) to any database collection directly to the database collection using the CLI command add-schema
or the Codehooks Studio application navigating to Collection/Settings/JSON-Schema.
Example: Defining a JSON Schema using the CLI
To ensure your data is consistent and secure, you can define a JSON Schema for your collections. This schema will validate the data structure and enforce data types.
Create a schema file (e.g., personSchema.json
) defining the structure of your data:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Person",
"type": "object",
"properties": {
"firstName": {
"type": "string",
"description": "The person's first name."
},
"lastName": {
"type": "string",
"description": "The person's last name."
},
"age": {
"type": "integer",
"description": "The person's age.",
"minimum": 0
},
"email": {
"type": "string",
"format": "email",
"description": "The person's email address."
},
},
"required": [
"firstName",
"lastName",
"email"
]
}
Use the CLI to add this JSON Schema to your collection:
codehooks add-schema --collection 'person' --schema './personSchema.json'
JSON-Schema validation errors and status code
In the event that clients sends data not following the JSON-Schema, a validator error will be thrown.
E.g. when the API posts a JSON object missing a required field a validator schemaError
error array of objects will be returned.
{
"schemaError": [
{
"instancePath": "",
"schemaPath": "#/required",
"keyword": "required",
"params": {
"missingProperty": "firstName"
},
"message": "must have required property 'firstName'"
}
]
}
Data validation JSON schema API
The following API methods allow you to programmatically manage JSON schemas for your collections, providing an alternative to using the CLI or Codehooks Studio for schema management.
setSchema(collection, schema)
Set a JSON schema for a collection to enforce data validation.
Parameters
- collection: name of the collection
- schema: JSON schema object
Returns Promise with the result of the operation
Code example
import { app, Datastore } from 'codehooks-js'
import { mySchema } from './schema.json'
async function setCollectionSchema(collection) {
const conn = await Datastore.open();
const result = await conn.setSchema(collection, mySchema);
return result;
}
export default app.init(async () => {
try {
const result = await setCollectionSchema('person');
console.log('Schema set successfully:', result);
} catch (error) {
console.error('Error setting schema:', error.message);
}
});
getSchema(collection)
Retrieve the JSON schema for a collection.
Parameters
- collection: name of the collection
Returns Promise with the JSON schema or null if not set
Code example
import {app, Datastore} from 'codehooks-js'
async function getCollectionSchema(req, res) {
const conn = await Datastore.open();
const {collection} = req.params;
try {
const schema = await conn.getSchema(collection);
res.json(schema);
} catch (error) {
res.status(400).json({error: error.message});
}
}
app.get('/get-schema/:collection', getCollectionSchema);
export default app.init();
removeSchema(collection)
Remove the JSON schema from a collection.
Parameters
- collection: name of the collection
Returns Promise with the result of the operation
Code example
import {app, Datastore} from 'codehooks-js'
async function removeCollectionSchema(req, res) {
const conn = await Datastore.open();
const {collection} = req.params;
try {
const result = await conn.removeSchema(collection);
res.json(result);
} catch (error) {
res.status(400).json({error: error.message});
}
}
app.delete('/remove-schema/:collection', removeCollectionSchema);
export default app.init();
Collection Management
The database API provides methods to create and drop collections, allowing you to manage the structure of your database.
createCollection(collection, options)
Creates a new collection in the database.
Parameters
- collection: (String) The name of the collection to create.
- options: (Object, optional) Additional options for creating the collection.
- cap: (Number, optional) Maximum number of documents in the collection.
- capdelay: (Number, optional) Milliseconds to wait before capping the collection.
- schema: (Object, optional) JSON Schema for validating documents in the collection. Must follow the JSON Schema standard.
Returns Promise that resolves with the result of the operation.
Simple code example
import { Datastore } from 'codehooks-js'
async function createSimpleCollection() {
const conn = await Datastore.open();
try {
const result = await conn.createCollection('simpleCollection');
console.log('Collection created:', result);
} catch (error) {
console.error('Error creating collection:', error);
}
}
Advanced example with schema and cap options
import { Datastore } from 'codehooks-js'
async function createAdvancedCollection() {
const conn = await Datastore.open();
try {
const options = {
cap: 100000,
schema: {
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "IoTLog",
"type": "object",
"properties": {
"deviceId": {
"type": "string",
"description": "Unique identifier for the IoT device"
},
"timestamp": {
"type": "string",
"format": "date-time",
"description": "Timestamp of the log entry"
},
"temperature": {
"type": "number",
"description": "Temperature reading from the device"
},
"humidity": {
"type": "number",
"description": "Humidity reading from the device"
},
"batteryLevel": {
"type": "number",
"minimum": 0,
"maximum": 100,
"description": "Battery level of the device"
}
},
"required": ["deviceId", "timestamp", "temperature", "humidity", "batteryLevel"]
}
};
await conn.createCollection('iotLogs', options);
console.log('IoT Log collection created successfully');
} catch (error) {
console.error('Error creating IoT Log collection:', error);
}
}
These examples demonstrate how to create a simple collection without any options, and how to create an advanced collection with a schema
dropCollection(collection)
Removes an existing collection from the database.
Parameters
- collection: (String) The name of the collection to drop.
Returns Promise that resolves with the result of the operation.
Code example
import { Datastore } from 'codehooks-js'
async function removeCollection() {
const conn = await Datastore.open();
try {
const result = await conn.dropCollection('oldCollection');
console.log('Collection dropped:', result);
} catch (error) {
console.error('Error dropping collection:', error);
}
}
These methods allow you to programmatically manage the collections in your database. Use createCollection
to add new collections and dropCollection
to remove existing ones. Be cautious when using dropCollection
, as it will permanently delete the collection and all its data.