API Maker

The framework for AI era

Database APIs

Auto Generated APIs

Connect a database. Every table and collection gets its REST APIs at once.

API Maker reads your databases and serves APIs for every table: list, read, save, update, delete, query, count, distinct values and streams. Use them straight on the table, or as schema APIs that check every write. No code to write for any of it.

See it live

Step through it, slow it down, or open the full canvas.

api-maker/features/auto-generated-apis-from-databaseLive
  • Request
  • Data
  • Generated
  • Rejected
Collections
0found
APIs
0for products
Last status
–HTTP
Rows streamed
0so far

Connect any of 8 databases. Pick the connection string from your Secret. API Maker connects and lists every database, table and collection.

How it works

  1. Connect any of 8 databases.

    Pick the connection string from your Secret. API Maker connects and lists every database, table and collection.

  2. Every table gets its APIs at once.

    A MongoDB collection gets 17 generated APIs, from get all and streams to aggregate. A SQL table gets 14. No code.

  3. Schema APIs double them.

    The schema is detected from the data (the first 100 documents, or the table columns). Its 17 schema APIs validate every write.

  4. Ask for exactly the data you need.

    find, sort, limit and select shape the answer on the server. skip, deep and getTotalCount are there too.

  5. Invalid data never reaches the table.

    A schema API answers 400 with a clear message for every field, and saves valid data with 201.

  6. Stream millions of rows.

    The stream APIs read and send 1000 rows at a time and wait for the client, so memory stays flat whatever the size.

What you get

Every operation you need

Get all, get by id, save one or many, master save, update by id, update many, remove by id or by query, query, count and distinct. On MongoDB also replace by id, array operations and aggregate.

Generated or schema APIs

Generated APIs work straight on the table. Schema APIs use the schema of the table to convert and validate every write, and to follow relations. The schema is detected for you and stays editable.

One query language

find, sort, skip, limit and select work the same on every database, with operators like $gt, $in, $and and $or. getTotalCount adds the total for paging.

Streams for big results

The stream APIs read 1000 rows at a time and wait for the client, so exporting millions of rows keeps memory flat.

Related data in one call

Populate related rows with deep, or filter on fields of related tables with find, even when they live in another database.

Secure from the start

Every API needs a token unless you make it public, and groups decide which APIs and fields each user can use.

The APIs of every table

Every table gets these APIs under /api/gen. Tables with a schema get them again under /api/schema, where each request goes through the schema first. The examples use the products table of the main database of an instance named shop, and admin as the API path of the account.

Base path/api/gen/<api path>/<instance>/<database>

APIMethod and pathWhat it doesExample
Get allGET/:tableRows of the table, filtered, sorted, paged and trimmed to some fields by the query string.
GET /api/gen/admin/shop/main/products?find={stock:{$gt:0}}&sort=-price&limit=10&select=name,price
Get all by streamGET/:table/streamThe same filters as get all. The rows are sent as a stream, for exports of any size.
GET /api/gen/admin/shop/main/products/stream?find={category:'mouse'}
Get by idGET/:table/get-by-id/:idOne row by its id. Add a column name after the id to find the row by that column instead.
GET /api/gen/admin/shop/main/products/get-by-id/1042
Save single or multiplePOST/:table/save-single-or-multipleInsert one row, or an array of rows in one call.
POST /api/gen/admin/shop/main/products/save-single-or-multiple[{ "name": "Mouse", "price": 19 }, { "name": "Keyboard", "price": 49 }]
Master savePOST/:table/master-saveA row with its related rows, following the relations of the schema: rows with an id are updated, the others inserted.
POST /api/schema/admin/shop/main/products/master-save{ "name": "Mouse", "price": 19, "brand_id": { "name": "Logi" } }
Array operationsMongoDB onlyPUT/:table/array-operationsPush, add to set, pull, pop or set items of an array field, in the documents that match find.
PUT /api/gen/admin/shop/main/products/array-operations{ "find": { "_id": 1042 }, "operations": [{ "operation": "push", "path": "tags", "dataToPush": ["wireless"] }] }
Update manyPUT/:table/update-manySet the same fields on every row that matches find.
PUT /api/gen/admin/shop/main/products/update-many{ "find": { "category": "mouse" }, "updateData": { "discount": 10 } }
Update by idPUT/:table/update-by-id/:idChange some fields of one row. upsert and returnDocument go in the query string.
PUT /api/gen/admin/shop/main/products/update-by-id/1042{ "price": 17 }
Replace by idMongoDB onlyPUT/:table/replace-by-id/:idReplace a whole document with the body.
PUT /api/gen/admin/shop/main/products/replace-by-id/1042{ "name": "Mouse", "price": 17, "stock": 40 }
Remove by idDELETE/:table/:idRemove one row by its id.
DELETE /api/gen/admin/shop/main/products/1042
QueryPOST/:table/queryfind, sort, skip, limit, select and deep in a JSON body, for filters too long for a URL.
POST /api/gen/admin/shop/main/products/query{ "find": { "price": { "$lt": 50 } }, "sort": { "price": 1 }, "limit": 10 }
Query by streamPOST/:table/query-streamThe query API, with the rows sent as a stream.
POST /api/gen/admin/shop/main/products/query-stream{ "find": { "stock": { "$gt": 0 } } }
Remove by queryPOST/:table/query/deleteRemove every row that matches find. A missing or empty find is refused.
POST /api/gen/admin/shop/main/products/query/delete{ "find": { "stock": 0 } }
AggregateMongoDB onlyPOST/:table/aggregateRun a MongoDB aggregation pipeline on the collection.
POST /api/gen/admin/shop/main/products/aggregate[{ "$match": { "stock": { "$gt": 0 } } }, { "$group": { "_id": "$category", "count": { "$sum": 1 } } }]
CountPOST/:table/countHow many rows match find.
POST /api/gen/admin/shop/main/products/count{ "find": { "category": "mouse" } }
DistinctGET/:table/distinct/:fieldUnique values of one or more fields. Add /asc or /desc after the fields to choose the order.
GET /api/gen/admin/shop/main/products/distinct/category
Distinct with queryPOST/:table/distinct/:fieldUnique values of the fields, among the rows that match find.
POST /api/gen/admin/shop/main/products/distinct/brand{ "find": { "category": "mouse" } }

An example

The 10 cheapest products in stock, with two fields and the totalrequest
GET /api/gen/admin/shop/main/products?find={"stock":{"$gt":0}}&sort=price&limit=10&select=name,price&getTotalCount=truex-am-authorization: <API user token>

admin is the API path of your account, shop the instance, main the database and products the table.

The same filter in the body of the query APIrequest
POST /api/schema/admin/shop/main/products/queryx-am-authorization: <API user token>{    "find": { "stock": { "$gt": 0 }, "category": { "$in": ["mouse", "keyboard"] } },    "sort": { "price": 1 },    "limit": 10}
The answer of every API has the same shaperesponse.json
{    "success": true,    "statusCode": 200,    "data": [        { "_id": "66f1c2…", "name": "Mouse", "price": 19 },        { "_id": "66f1c3…", "name": "Keyboard", "price": 49 }    ],    "totalCount": 42}

Good to know

  • Replace by id, array operations and aggregate are MongoDB only, which is why a SQL table gets 14 APIs instead of 17.
  • Schema APIs need a schema for the table. Generated APIs work without one, and do not validate what you save.
  • TiDB and Percona XtraDB are connected as MySQL instances.

Questions

What is the difference between generated and schema APIs?

Generated APIs (/api/gen) run your request on the table as it is. Schema APIs (/api/schema) first apply the schema of the table: type conversions, default values, validations, encryption and relations. Both exist for every table that has a schema.

Where does the schema come from?

API Maker detects it: from the columns of a SQL table, or from the first 100 documents of a MongoDB collection. You can edit it afterwards to add validations and relations.

Do I have to restart anything when I add a table?

No. The generated APIs are generic routes, so a new table is served by the same handlers.

Can I add my own logic to these APIs?

Yes. Pre and post hooks run your TypeScript before and after any generated API, and custom APIs cover everything else.