Skip to main content

CRUD Operations

Introduction​

Once you created your entities, you probably want to interact with them. It is easy to connect your client to your Manifest backend.

Manifest provides out-of-the-box CRUD endpoints through the REST API or the JS SDK.

CRUD operations can be restricted using access policies.

Using the REST API​

Manifest exposes a REST API for CRUD operations. The OpenAPI documentation is automatically generated on http://localhost:1111/api. Have a look!

For CRUD endpoints, this prefix is followed by collections for collections entities and singles for single entities and by the slug of your entity (you can change it in the entity params)

Examples:

  • http://localhost:1111/api/collections/cats gets the list of the cats
  • http://localhost:1111/api/singles/home-content gets the home content
tip

In addition to CRUD endpoints that are generated automatically, you also can create your own custom endpoints to add your custom logic.

Using the JavaScript SDK​

The Manifest JS SDK is used to fetch and manipulate your data from your JS client using an elegant and human-friendly interface.

The SDK can be integrated in any frontend stack app like React, Vue, Svelte.... Or even by another server using NodeJS!

Install it via the terminal:

npm i @mnfst/sdk

Use the SDK directly in your favorite frontend:

Example SDK usage
import Manifest from '@mnfst/sdk'

// Initialize client with default backend URL: http://localhost:1111.
const manifest = new Manifest()

// Initialize client with custom base URL.
const manifest = new Manifest('https://example.com')

// Perform CRUD operations...
const cats = await manifest.from('cats').find()

Collections​

The following CRUD operations can be done on collections entities. A collection is a list of items that share a similar schema.

Get a list of items​

This operation will fetch a list of items from a collection.

Request URL: GET /api/collections/:slug

Example HTTP Request
GET /api/collection/users
Example HTTP Response
{
"data": [
{
"id": 1,
"name": "Lara"
},
{
"id": 2,
"name": "Karl"
}
],
"currentPage": 1,
"lastPage": 1,
"from": 1,
"to": 10,
"total": 3,
"perPage": 10
}

List filters

You can filter by property to refine the list of items. Use suffix to pass logic to it:

SuffixDescriptionExample
_eqequalsisActive_eq=true
_neqnot equalsname_neq=alice
_gtgreater thanbirthdate_gt=2020-01-01
_gtegreater than or equalage_gte=4
_ltless thanamount_lt=400
_lteless than or equalamount_lte=400
_likelikename_like=%bi%
_inincluded incustomer_in=1,2,3

Pagination

All list requests are paginated by default. Just use the page parameter to choose your page and the perPage param if you want to change the number of items per page.

ParamDescriptionExample
pageThe number of the page requestedpage=3
perPageThe number of items of each pageperPage=40

Order

Order your list by a defined property. By default the results are ordered by id in a DESC order and thus shows the new ones first.

ParamDescriptionExample
orderByThe name of property you want to order by.orderBy=age
orderAscending 'ASC' or Descending 'DESC'order=DESC

Get a single item​

This operation will fetch a single item based on its ID.

Request URL: GET /api/collections/:slug/:id

Example HTTP Request
GET /api/collections/cats/34
Example HTTP Response
{
"name": "Mina",
"description": "A really cute cat"
}

Create a new item​

This operation will create a new item and store it in the database. The newly created item is returned as response.

Request URL: POST /api/collections/:slug

Example HTTP Request
POST /api/collections/pokemons
Content-Type: application/json
Body:
{
"name": "Pikachu",
"type": "electric",
"level": 3,
}

Example HTTP Response
{
"id": 25,
"name": "Pikachu",
"type": "electric",
"level": 3,
}

Update an item​

This operation will replace an existing item by the payload provided in the request and returns the updated item.

Unlike partial updates, this operation will replace the whole item by the new one. Missing or empty properties will delete the previous ones.

Request URL: PUT /api/collections/:slug/:id

Example HTTP Request
PUT /api/collections/pokemons/25
Content-Type: application/json
Body:
{
"name": "Raichu",
"type": "electric",
"level": 8
}

Example HTTP Response
{
"id": 25,
"name": "Raichu",
"type": "electric",
"level": 8
}

Patch an item​

This operation will partially replace an existing item and return the updated item.

Unlike fully replacement, this operation will only modify the properties provided in the payload and leave the other ones as they are.

Request URL: PATCH /api/collections/:slug/:id

Example HTTP Request
PATCH /api/collections/pokemons/25
Content-Type: application/json
Body:
{
"level": 5,
}
Example HTTP Response
{
"id": 25,
"name": "Pikachu",
"type": "electric",
"level": 5
}

Delete an item​

This operation will delete permanently an item from the database. This is an irreversible action. The deleted item is returned in the response.

Request URL: DELETE /api/collections/:slug/:id

Example HTTP Request
DELETE api/collections/cats/60
Example HTTP Response
{
"name": "Fido",
"description": "A cute black cat"
}

Singles​

The following operations can be done on singles entities. As there is only a single item per entity, there is no list-related operations, and single items cannot be deleted as we always want to return an object, even if empty.

Get a single item​

Request URL: GET /api/singles/:slug

Example HTTP Request
GET /api/singles/homepage
Example HTTP Response
{
"title": "My title",
"description": "Welcome to my website!"
}

Update an item​

This operation will replace an existing item by the payload provided in the request. Unlike partial updates, this operation will replace the whole item by the new one. Missing or empty properties will delete the previous ones.

Request URL: PUT /api/singles/:slug

Example HTTP Request
PUT /api/singles/homepage
Content-Type: application/json
Body:
{
"title": "My new title",
"description": "My new description"
}

Example HTTP Response
{
"title": "My new title",
"description": "My new description"
}

Patch an item​

This operation will partially replace an existing item. Unlike fully replacement, this operation will only modify the properties provided in the payload an leave the other ones as they are.

Request URL: PATCH /api/singles/:slug

Example HTTP Request
PATCH /api/singles/homepage
Content-Type: application/json
Body:
{
"title": "My new title",
}
Example HTTP Response
{
"title": "My new title",
"description": "Welcome to my website!"
}

Work with relations​

If you added relationships between your entities, you probably want to include them in the CRUD operations.

Load relations​

You can specify which relations you want to load with your entities in your query. Eager relations are loaded automatically.

  // Fetch entities with 2 relations.
const cities = await manifest
.from('cities')
.with(['region', 'mayor'])
.find()

// Fetch nested relations.
const cities = await manifest
.from('cities')
.with(['region', 'region.country', 'region.country.planet'])
.find()

Filter by relation​

Once the relation is loaded, you can also filter items by their relation id or properties.

  // Get all cats that belong to owner with id 1.
const cats = await manifest
.from('cats')
.with(['owner'])
.where('owner.id = 1')
.find()

// Get all cats that have an owner with name "Jorge".
const cats = await manifest
.from('cats')
.with(['owner'])
.where('owner.name = Jorge')
.find()

Store relations​

To store or update an item with its relations, you have to pass the relation id(s) as a property that end with Id for many-to-one and Ids for many-to-many like companyId or tagIds

// Store a new player with relations Team and Skill.
POST http://localhost:1111/api/dynamic/players
Content-Type: application/json
{
"name": "Mike",
"teamId": 10,
"skillIds": [1,2,3,4,5]
}
note

When storing many-to-many relations, you always need to pass an array, even if you just have one single value.

Update relations​

As for updating properties, you can either do a full replacement using the update function (PUT) or a partial replacement using the patch function (PATCH).

// Replaces the whole skill relations by the new skillIds array.
PUT http://localhost:1111/api/dynamic/players/1
Content-Type: application/json
{
name: 'Mike',
teamId: 10,
skillIds: [10, 11]
}

// Updates the team without changing the skills or the name.
PATCH http://localhost:1111/api/dynamic/players/1
Content-Type: application/json
{
teamId: 5,
}