CRUD APIs & Routes
CRUD is an acronym that stands for Create, Read, Update, and Delete operations. These operations are fundamental to managing data within databases, extending their principles to the architectural design of REST APIs. As an API developer, you leverage the CRUD framework for giving the best API experience to your consumers.
Beeceptor supports CRUD routes to build JSON Rest APIs. This makes it easier to speed up the development, integration, and testing phases of software projects. This feature is particularly advantageous for projects at their inception, requiring CRUD capabilities for one or more entities. Here’s a brief overview of the CRUD operations on a given entity:
- Create: Adding new data or objects to the application.
- Read: Retrieving or fetching data from the application.
- Update: Modifying existing data within the application.
- Delete: Removing data from the application.
Configuring CRUD Routes
Beeceptor has designed its CRUD Routes to prioritize ease of use and efficiency. Follow these simple steps to begin with a new HTTP endpoint:
-
Open the CRUD API creator page at Beeceptor.
-
Enter the base path for the entity you're working with. E.g. for a
Product
entity, you could use/products
or/api/products
as your base path. You don't need to specify any trailing slashes. -
Click on the Create CRUD API button. This action will redirect you to the newly created mock server, ready for use.
-
Beeceptor automatically generates the necessary JSON REST APIs. This base path serves as the foundation for all CRUD operations, which are distinguished by the HTTP method (GET, POST, PUT, DELETE) in the request.
-
The final step involves creating the JSON object you wish to add. Copy the API URLs and send a
POST
request to the appropriate CRUD path to create an object.
Existing Endpoint
You also have the flexibility to add CRUD routes to an existing mock server or endpoint. Simply navigate to the 'Mock Rules' section and select the Create New CRUD button.
REST APIs
Upon defining a CRUD route, several API endpoints are automatically generated. For instance, if you want to manage Products with a relative API base path of /api/products
, specifying this single route will create the following APIs for managing the Product entity:
Purpose | HTTP Method | URL |
---|---|---|
Create a product | POST | /api/products |
Retrieve all products | GET | /api/products |
Retrieve one product | GET | /api/products/{id} |
Update a product | PUT | /api/products/{id} |
Partial update a product | PATCH | /api/products/{id} |
Delete a product | DELETE | /api/products/{id} |
Entity ID
The default identifier for objects is the id
field. However, you can customize this route to use an alternative field name, such as entity_id
, objectId
, etc. If the identifier field is omitted in the create request (POST API request), a random 10-character record ID is generated by Beeceptor.
Data Bucket & JSON Objects
Beeceptor creates a unique data bucket for each endpoint, ensuring data partition at the endpoint level. Each endpoint can have multiple CRUD routes, and all the associated objects are stored within a single data bucket as JSON documents. This strategy not only facilitates data separation but also ensures a robust JSON handling experience, supporting complex data structures like nested objects, lists, and primitive data types.
CRUD Operations (e.g. Product)
The operations described below are with an assumption of managing a Product entity through the CRUD route /api/products
.
Creating Objects
To create objects, send a valid JSON object through a POST
HTTP request to the entity's base API path. The JSON object will be stored as provided, without any schema change or validation by Beeceptor. If the request payload lacks an id
(identifier field), Beeceptor will automatically generate a unique identifier for the new object.
Parameter | Value |
---|---|
HTTP Method | POST |
API URL | https://<endpoint-name>.proxy.beeceptor.com/api/products |
Request payload | { "price": 200, "name": "Guitar" } |
Response status code | 200 |
Response payload | { "id": "ff055a745667b8ffab51", "price": 200, "name": "Guitar" } |
Retrieve All Objects
Use the GET
API to fetch all objects stored for this route. The response will be a JSON Array containing a list of previously created objects. If no objects exist under this CRUD route, an empty array []
is returned, indicating a successful operation.
Parameter | Value |
---|---|
HTTP Method | GET |
API URL | https://<endpoint-name>.proxy.beeceptor.com/api/products |
Response status code | 200 |
Response payload | [ { "id": "ff055a745667b8ffab51", "price": 300, "name": "Guitar" }, { "id": "83f1a6b994ba9b89e582", "price": 200, "name": "Violin" } ] |
Filters & Sorting: This API supports both filters and sorting during retrieval. Check out the next section for more details.
Retrieve An Object
Use this GET
API to fetch a specific object by its identifier. The response will be a JSON object.
Parameter | Value |
---|---|
HTTP Method | GET |
API URL | https://<endpoint-name>.proxy.beeceptor.com/api/products/{id} |
Response status code | 200 - Indicates success. 404 - Returned if an object with the specified ID cannot be found. |
Response payload | { "id": "83f1a6b994ba9b89e582", "price": 200, "name": "Violin" } |
Update An Object (Whole)
Use the PUT
API to modify an object. The JSON payload included in the HTTP request will overwrite the existing object associated with the specified ID. The identifier field will not be altered during this operation.
Parameter | Value |
---|---|
HTTP Method | PUT |
API URL | https://<endpoint-name>.proxy.beeceptor.com/api/products/{id} |
Request payload | { "price": 500, "name": "Guitar" } |
Response status code | 200 |
Response payload | { "id": "ff055a745667b8ffab51", "price": 500, "name": "Guitar" } |
Update An Object (Partial)
Use the PATCH
API for partial updates or to modify specific fields of an object. The operation updates only the fields included in the HTTP request payload, leaving the rest of the object unchanged. For instance, in the request below, only the product's price is updated.
Parameter | Value |
---|---|
HTTP Method | PATCH |
API URL | https://<endpoint-name>.proxy.beeceptor.com/api/products/{id} |
Request payload | { "price": 500 } |
Response status code | 200 |
Response payload | { "id": "ff055a745667b8ffab51", "price": 500 } |
Delete An Object
Use this API to permanently remove an object from storage. Once deleted, the object cannot be recovered.
Parameter | Value |
---|---|
HTTP Method | DELETE |
API URL | https://<endpoint-name>.proxy.beeceptor.com/api/products/{id} |
Response status code | 200 - Indicates success. 404 - Returned if an object with the specified ID cannot be found. |
Response payload | { "success": true } |
Filters
Beeceptor includes a comprehensive support for filtering when working with CRUD routes. This functionality primarily offers developers a flexible way to retrieve specific subsets of data. Let's explore this feature in more detail, using a Product entity as an example.
No Filters - Retrieve All Products
Imagine there are 10 objects stored in Beeceptor for the Product entity. When using the GET API without any filters on this entity, the response looks like the following. By default, this API returns all the objects stored for the Product entity.
Request
GET https://<endpoint-name>.proxy.beeceptor.com/api/products/
Response
[
{ "id": "ff055", "price": 300, "name": "Guitar" },
{ "id": "83f1a", "price": 200, "name": "Violin" },
{ "id": "cd120", "price": 150, "name": "Keyboard" },
{ "id": "29c7f", "price": 400, "name": "Drum Set" },
{ "id": "8e9d7", "price": 100, "name": "Flute" },
{ "id": "a6f1d", "price": 220, "name": "Trumpet" },
{ "id": "f48b6", "price": 270, "name": "Saxophone" },
{ "id": "c2a91", "price": 320, "name": "Electric Guitar" },
{ "id": "d891f", "price": 180, "name": "Clarinet" },
{ "id": "e1d57", "price": 350, "name": "Bass Guitar" }
]
Filters - Find products with name 'Guitar'
To refine the search results, you can pass query parameters in the GET API's URL. For example, to retrieve only products named "Guitar", the request would look like the following with ?name=Guitar
:
Request
GET https://<endpoint-name>.proxy.beeceptor.com/api/products?name=Guitar
Response
[
{
"id": "ff055",
"price": 300,
"name": "Guitar"
}
]
Filters - Find product with price lower than 500
Beeceptor supports number comparison in the CRUD APIs for object retrieval. You can pass query parameters like ?price<200
to retrieve all products cheaper than 200. The request would look as follows:
Request
GET https://<endpoint-name>.proxy.beeceptor.com/api/products?price<200
Response
[
{
"id": "cd120",
"price": 150,
"name": "Keyboard"
},
{
"id": "8e9d7",
"price": 100,
"name": "Flute"
},
{
"id": "d891f",
"price": 180,
"name": "Clarinet"
}
]
You can use other comparison operators as well. For instance, ?price=200
retrieves all products with a price of exactly 200
. The supported operators include:
Operator | Description |
---|---|
= | Compares the field's value to be exactly the same as the given value |
!= | Compares the field's value to ensure it is not equal to the given value |
>= | Compares the field's value to check if it is greater than or equal to the given value |
<= | Compares the field's value to check if it is less than or equal to the given value |
< | Compares the field's value to check if it is less than the given value |
> | Compares the field's value to check if it is greater than the given value |
Multiple Filters
You can combine multiple filters to refine your results. For instance, ?name=Guitar&price>200
retrieves all products named "Guitar" that are more expensive than 200.
Request
GET https://<endpoint-name>.proxy.beeceptor.com/api/products?name=Guitar&price>200
Response
[
{
"id": "ff055",
"price": 300,
"name": "Guitar"
}
]
List Inclusion
For the same field, multiple equality comparisons are merged into a list operator. For example, ?name=Guitar&name=Violin
returns products named either "Guitar" or "Violin".
Request
GET https://<endpoint-name>.proxy.beeceptor.com/api/products?name=Guitar&name=Violin
Response
[
{
"id": "ff055",
"price": 300,
"name": "Guitar"
},
{
"id": "83f1a",
"price": 200,
"name": "Violin"
}
]
You can also use "not equals" as ?name!=Guitar&name!=Violin
to find objects that are neither named "Guitar" nor "Violin". Behind the scenes, values with the same keys (field names) are used as list operators (in []
and not in []
), allowing for inclusion and exclusion searches.
More Tricks
- Dot Notation: You can use dot notation to query fields deep within an object. For example,
category.secondary=hand-instrument
will search forcategory
at the root level and thesecondary
field inside it. - Boolean Comparisons: Values passed as
true
andfalse
in query parameters are compared as boolean values. - To allow a comma as part of a value, you need to force it as a string. For example:
field="a,b"
.
Sort
The syntax for forcing a sort action is ?sort=<field-name>
. Here, you can pass the names of one or more fields (comma-separated) to retrieve objects sorted by those fields. The default sorting order is ascending. You can prefix the field name with -
to get a descending order.
For example, ?sort=-price,name
ensures the list of objects is sorted by price in descending order and by name in ascending order in the response array.
Request
GET https://<endpoint-name>.proxy.beeceptor.com/api/products?sort=-price,name
Response
[
{"id":"29c7f","price":400,"name":"Drum Set"},
{"id":"c2a91","price":320,"name":"Electric Guitar"},
{"id":"ff055","price":300,"name":"Guitar"},
{"id":"f48b6","price":270,"name":"Saxophone"},
{"id":"a6f1d","price":220,"name":"Trumpet"},
{"id":"83f1a","price":200,"name":"Violin"},
{"id":"d891f","price":180,"name":"Clarinet"},
{"id":"cd120","price":150,"name":"Keyboard"},
{"id":"8e9d7","price":100,"name":"Flute"}
]
Pagination
Beeceptor's CRUD routes support two methods for pagination: Limit/Offset and Page/Size. You can use either of these pairs to paginate through records in the API response.
Limit and Offset
- Use
limit
to restrict how many objects are returned in the response. - The
offset
indicates how many to skip.
You can combine limit with sort and filter actions to build complex object retrieval use cases. Here is an example to retrieve a list of 5 products, sorted by highest-priced items first:
Request
GET https://<endpoint-name>.proxy.beeceptor.com/api/products?limit=5&sort=-price
Response
[
{"id":"29c7f","price":400,"name":"Drum Set"},
{"id":"c2a91","price":320,"name":"Electric Guitar"},
{"id":"ff055","price":300,"name":"Guitar"},
{"id":"f48b6","price":270,"name":"Saxophone"},
{"id":"a6f1d","price":220,"name":"Trumpet"}
]
Page and Size
For using this pagination method, the keywords in query parameters are as follows:
page
: Specifies the page number of the data to be retrieved, starting from 1.size
: Specifies the number of items to be returned per page. (optional, default 10)
Here is an example to retrieve a list of 5 products from the first page, sorted by highest-priced items:
Request
GET https://<endpoint-name>.proxy.beeceptor.com/api/products?page=1&size=5&sort=-price
Response
[
{"id": "29c7f", "price": 400, "name": "Drum Set"},
{"id": "c2a91", "price": 320, "name": "Electric Guitar"},
{"id":"ff055","price":300,"name":"Guitar"},
{"id":"f48b6","price":270,"name":"Saxophone"},
{"id":"a6f1d","price":220,"name":"Trumpet"}
]
To build paging links for your application, you can use the following examples for CRUD routes:
?page=1
: Fetches the first page of results.?page=2&size=2
: Fetches the second page with 2 items per page.?page=3&size=10
: Fetches the third page with 10 items per page.?page=1&sort=price
: Fetches the first page of results sorted by price in ascending order.
CRUD Behavior
HTTP Status Codes
Beeceptor adheres to standard best practices for JSON REST APIs, utilizing HTTP status codes for errors and maintaining a consistent error structure. Here are a few examples of error responses:
A 400
HTTP status code is returned if the request payload contains malformed JSON:
{
"error": {
"code": "invalid_json_body",
"message": "Invalid JSON in request body"
}
}
A 404
HTTP status code is returned if an object with the given ID cannot be found:
{
"error": {
"code": "bad_request",
"message": "resource not found"
}
}
Storage Limits
CRUD routes are offered as a premium feature, with limits on the maximum number of objects per endpoint varying by subscription plan. The Individual plan accommodates up to 25 objects, whereas the Team plan supports up to 100 objects across all CRUD routes within an endpoint.
Subscription plan | Maximum number of objects allowed per endpoint |
---|---|
Free | 10 |
Individual | 25 |
Team | 100 |
Scale | 500 |
Enterprise | 1000 |
Automatic Purging
When these limits are exceeded, Beeceptor initiates an automatic purging to free up space for new objects. This is done by tracking the last updated date, and the oldest records, based on creation or update, are automatically removed.
No Business Logic
This feature is particularly beneficial for storing and retrieving JSON objects while the APIs are under development to facilitate quicker integration and prototyping. These CRUD APIs operate without incorporating any business logic. For instance, two objects within an entity (CRUD path) may have varying schemas/structures, or missing the unique constraints on the id
field, among other possibilities.
Higher Security
Beeceptor's mock servers are publicly accessible online, simplifying API simulation for testing and development. The CRUD routes defined here are also open for anyone to retrieve objects. To enhance security, consider enabling authentication via HTTP headers. For details, see enabling authentication for an endpoint.
Matching Mock Rules
Beeceptor offers the flexibility of combining mock rules with CRUD routes, enhancing your API development and testing capabilities. The CRUD routes in Beeceptor are designed to handle requests based on a specified request path prefix, effectively capturing all requests that match this prefix.
The mechanism for rule matching within an endpoint is determined by the order of priority of the rules. To ensure that CRUD routes are evaluated properly and not overshadowed by other mock rules, they should be prioritized at the top of the list. You can adjust the priority of a rule by dragging it to a higher position in the list.