Query parameters¶
The read APIs of a table take their options in the URL : ?limit=10&sort=-customer_id. The query APIs take the same keys in their JSON body.
In short
findfilters,sortorders,skipandlimitmake pages,selectpicks the columns,deepbrings related rows.getTotalCount=trueadds the total number of matching rows to the answer.- Without
limit, a read returns every row that matches. - Values are JSON5 :
find={first_name:'Bob'}works without quotes around the keys.
The examples read this table, customers of the instance mysql8.
| customer_id | first_name | last_name | last_update | pincode | isActive |
|---|---|---|---|---|---|
| 1 | Bob | Lin | 2022-11-14 04:34:58 | 382345 | 1 |
| 2 | Alice | Page | 2022-10-15 02:10:40 | 382346 | 1 |
| 3 | Mallory | Brown | 2022-09-13 03:44:05 | 382347 | 1 |
| 4 | Eve | Mathly | 2022-11-12 01:59:33 | 382348 | 1 |
| 5 | Eve | Page | 2022-11-12 01:59:33 | 382349 | 1 |
The params¶
| Param | Example | What it does |
|---|---|---|
| find | ?find={first_name:'Bob',pincode:{$gte:382345}} |
Filters with the operators of MongoDB, on every database. |
| a column | ?first_name=Bob,Alice |
A column name is a filter too. See A column as a query param. |
| skip | ?skip=20 |
Leaves out the first rows. |
| limit | ?limit=10 |
At most this many rows. |
| sort | ?sort=-last_update,first_name |
The order. - for descending. |
| select | ?select=first_name,last_name |
Only these columns. -password : all but this one. |
| deep | ?deep=state_id |
Puts the related row in place of its id. |
| getTotalCount | ?getTotalCount=true |
Adds totalCount : the rows that match, before skip and limit. |
| upsert | ?upsert=true |
Inserts the row when the id is not there. |
| returnDocument | ?returnDocument=before |
Answers the row as it was before the change. |
| throwErrorIfRecordNotFound | ?throwErrorIfRecordNotFound=true |
Answers 404 for an unknown id, in place of data: null. |
Which API takes which¶
| API | What it takes |
|---|---|
| Get all, get all by stream, distinct | Every read param of the URL, and columns as filters. |
| Get by id | select and deep. |
| Save single or multiple, master save | select and deep, which shape the answer, and returnData=false. |
| Update by id, replace by id | select, deep, upsert, returnDocument, throwErrorIfRecordNotFound. |
| Remove by id | select, deep, throwErrorIfRecordNotFound. |
| Query, query by stream | The same keys, in the JSON body. |
| Count, distinct with query, update many, remove by query | Their own JSON body, with a find. See the page of each API. |
skip¶
Leaves out the first rows. With limit, it makes pages : page 3 of 10 rows is skip=20&limit=10.
- A whole number.
0, or noskip, leaves out nothing. - Always
sortwhen you make pages. Without an order, the database may send the rows in any order : a page may repeat a row or miss one.
limit¶
At most this many rows.
{
"success": true,
"statusCode": 200,
"data": [
{ "customer_id": 1, "first_name": "Bob", "last_name": "Lin" },
{ "customer_id": 2, "first_name": "Alice", "last_name": "Page" }
]
}
- Without
limit, get all and the query APIs return every row that matches. Give alimitas soon as a table can grow. - To read a whole big table, use a stream (get all by stream) : the rows go out as they come, without filling the memory of the server.
sort¶
Orders the rows. Name the columns, with - in front of a column for descending order.
In the body of the query APIs, sort is a text or an object :
- Spaces around the commas are fine.
- On MongoDB, a nested field sorts too :
sort=address.city. - Sorting a big table on a column without an index is slow. Index Maker finds the queries that need an index.
getTotalCount¶
getTotalCount=true adds totalCount to the answer : how many rows match the filter, before skip and limit. One call gives the page and the total.
{
"success": true,
"statusCode": 200,
"data": [
{ "customer_id": 1, "first_name": "Bob", "last_name": "Lin" },
{ "customer_id": 2, "first_name": "Alice", "last_name": "Page" }
],
"totalCount": 5
}
- It works on get all, the query API and the two streams. A stream sends
totalCountafter the rows. - The count is a second query on the database. On a very big table with a hard filter, it costs as much as the query itself.
- Need the number only ? Call the count API.
upsert¶
upsert=true makes update by id and replace by id insert the row when the id is not there.
| Row 999 | What happens | Answer |
|---|---|---|
| is there | It is updated with the body. | The row after the change. |
| is not there | It is inserted : customer_id: 999 and the body. |
The new row. |
- Without
upsert, an unknown id changes nothing, and the answer isdata: null. - An inserted row is checked like a new row : with a schema, every
requiredcolumn must be in the body.
returnDocument¶
Which version of the row update by id and replace by id answer : after the change (the default), or before it. It changes the answer only, never what is saved.
{
"success": true,
"statusCode": 200,
"data": { "customer_id": 1, "first_name": "Bob", "last_name": "Lin", "pincode": 382345 }
}
selectanddeepapply to the version in the answer.- With
upsert, a row that was inserted had no version before :beforeanswersnull.
throwErrorIfRecordNotFound¶
For update by id, replace by id and remove by id. With true, an unknown id answers 404 with the message Record not found. Without it, the answer is 200 with data: null.
{ "success": false, "statusCode": 404, "errors": [ { "code": 404, "message": "Record not found." } ] }
Write them right¶
- Values are JSON5 :
find={first_name:'Bob'}needs no quotes around the keys, and takes single quotes. Strict JSON works too. - Encode the value for the URL when your client does not :
find=%7Bfirst_name%3A'Bob'%7D. The API Testing page andg.sys.dbdo it for you. - In the body of the query APIs, the same keys are plain JSON :
{ "find": { "first_name": "Bob" }, "sort": "-customer_id", "skip": 0, "limit": 10, "select": "first_name,last_name", "getTotalCount": true }
- In a deep item,
skip,limitandsortapply to the related rows of each row. - From code,
queryParamsofg.sys.db.getAlltakes the same keys, as objects : see the code examples. - The schema APIs convert the values of
findto the types of the schema :"8"matches the number8. The generated APIs compare what you send as it is.