REST from your database catalog
    DocumentationCheat sheetQuestionsDownloadSource
    Questions
    • How do I...?
    Start here
    • Getting started
    • What a table becomes
    • Compared with PostgREST
    Setting up
    • Tables, columns and relations
    • Security and hooks
    • Writes and procedures
    • Prefer: return=representation
    • Node, Fastify, Express
    Reading
    • select
    • /{key}
    • relation(...)
    • order
    • limit, offset
    • relation.order, .limit
    • count
    • count(), sum(), avg()...
    • "name"
    Filtering
    • eq, neq
    • gt, gte, lt, lte
    • in
    • like, ilike
    • match, imatch
    • is
    • ov, cs, cd
    • not
    • relation.column
    • or, and
    Databases
    • Supported databases
    • Adding a database
    Reference
    • Cheat sheet
    • Errors
    Start here

    What a table becomes

    Every endpoint restloom serves for a table, and the options that turn each one on.

    Every table or view you expose becomes a resource named after it: a todos table is served at /todos. Which requests it accepts depends on two things only: whether the table has a primary key, and which writes the server allows, for this table in resources.todos.write or for every table in a top-level write.

    Try the options

    Tick what the server allows on a todos table. The endpoints that stay grey answer 405 method_not_allowed.

    resources: {
        todos: { write: { create: true, update: true } },
    }
    • GET/todos

      Reads a page of rows; filters, embeds, order and limit apply.

      Answers 200 and an array. Needs nothing more.

    • GET/todos/{key}

      Reads one row by its key.

      Answers 200 and an object, or 404 when there is no such row. Needs a primary key.

    • POST/todos{ }

      Body: a row. Creates one row.

      Answers 201 with no body, or with the row. Needs create.

    • POST/todos[ ]

      Body: an array of rows. Creates several rows in one statement: all of them, or none if one is refused. Up to 1000 by default.

      Answers 201 with no body, or with the rows. Needs create.

    • PATCH/todos/{key}{ }

      Body: a row. Changes some columns of one row.

      Answers 204, or 200 with the row. Needs update and a key.

    • DELETE/todos/{key}

      Deletes one row.

      Answers 405 method_not_allowed. Needs delete and a key.

    • PATCH/todos?filters{ }

      Body: a row. Changes every row the filters match. At least one filter is required.

      Answers 405 method_not_allowed. Needs update and bulk.

    • DELETE/todos?filters

      Deletes every row the filters match. At least one filter is required.

      Answers 405 method_not_allowed. Needs delete and bulk.

    write: true is a shortcut for create, update and delete on every visible column, without bulk. create and update also take a list of columns instead of true, to allow only those.

    Bulk endpoints

    Creating in bulk needs nothing more than create: POST an array instead of one object, and every row is written by a single statement. If one row is refused, none is written. All the rows must name the same columns, and a body holds at most limits.bodyRows rows, 1000 by default.

    POST /tags?select=id,name
    Prefer: return=representation
    
    [{ "id": 6, "name": "weekend" }, { "id": 7, "name": "errands" }]

    Asking the database...

    With bulk: true, PATCH and DELETE also work on the collection, on every row the filters match: DELETE /steps?priority=lt.3. A bulk request with no filter at all answers filter_required, so no request can rewrite or empty a table by accident.

    What is not an endpoint

    • No nested paths: /tags/3/todos does not exist. To get a tag's todos, embed them (/tags/3?select=name,todos(name)) or filter (/todos?tags.id=eq.3).
    • No PUT: a PATCH changes the columns it names and leaves the others alone.
    • No path for a table you did not expose, or for a junction table set to expose: false.

    Anything else your API needs, such as completing a todo or searching, is a procedure: a database function at a path you choose.

    Procedures, in Writes and procedures

    The tables of this site

    The database in this page runs with these options. Each table's endpoints follow from them; the requests below show the answers, refusals included.

    /users

    nothing: read-only

    • GET/users

      Reads a page of rows; filters, embeds, order and limit apply.

      Answers 200 and an array. Needs nothing more.

    • GET/users/{key}

      Reads one row by its key.

      Answers 200 and an object, or 404 when there is no such row. Needs a primary key.

    • POST/users{ }

      Body: a row. Creates one row.

      Answers 405 method_not_allowed. Needs create.

    • POST/users[ ]

      Body: an array of rows. Creates several rows in one statement: all of them, or none if one is refused. Up to 1000 by default.

      Answers 405 method_not_allowed. Needs create.

    • PATCH/users/{key}{ }

      Body: a row. Changes some columns of one row.

      Answers 405 method_not_allowed. Needs update and a key.

    • DELETE/users/{key}

      Deletes one row.

      Answers 405 method_not_allowed. Needs delete and a key.

    • PATCH/users?filters{ }

      Body: a row. Changes every row the filters match. At least one filter is required.

      Answers 405 method_not_allowed. Needs update and bulk.

    • DELETE/users?filters

      Deletes every row the filters match. At least one filter is required.

      Answers 405 method_not_allowed. Needs delete and bulk.

    GET /users/2

    Asking the database...

    POST /users
    
    { "id": 9, "name": "Zoe" }

    Asking the database...

    /todos

    write: {create: ["name", "status", "owner_id", "estimate"], update: ["name", "status", "owner_id"], delete: false}

    • GET/todos

      Reads a page of rows; filters, embeds, order and limit apply.

      Answers 200 and an array. Needs nothing more.

    • GET/todos/{key}

      Reads one row by its key.

      Answers 200 and an object, or 404 when there is no such row. Needs a primary key.

    • POST/todos{ }

      Body: a row. Creates one row.

      Answers 201 with no body, or with the row. Needs create.

    • POST/todos[ ]

      Body: an array of rows. Creates several rows in one statement: all of them, or none if one is refused. Up to 1000 by default.

      Answers 201 with no body, or with the rows. Needs create.

    • PATCH/todos/{key}{ }

      Body: a row. Changes some columns of one row.

      Answers 204, or 200 with the row. Needs update and a key.

    • DELETE/todos/{key}

      Deletes one row.

      Answers 405 method_not_allowed. Needs delete and a key.

    • PATCH/todos?filters{ }

      Body: a row. Changes every row the filters match. At least one filter is required.

      Answers 405 method_not_allowed. Needs update and bulk.

    • DELETE/todos?filters

      Deletes every row the filters match. At least one filter is required.

      Answers 405 method_not_allowed. Needs delete and bulk.

    PATCH /todos/3?select=name,status
    Prefer: return=representation
    
    { "status": "open" }

    Asking the database...

    DELETE /todos/3

    Asking the database...

    /tags

    write: true

    • GET/tags

      Reads a page of rows; filters, embeds, order and limit apply.

      Answers 200 and an array. Needs nothing more.

    • GET/tags/{key}

      Reads one row by its key.

      Answers 200 and an object, or 404 when there is no such row. Needs a primary key.

    • POST/tags{ }

      Body: a row. Creates one row.

      Answers 201 with no body, or with the row. Needs create.

    • POST/tags[ ]

      Body: an array of rows. Creates several rows in one statement: all of them, or none if one is refused. Up to 1000 by default.

      Answers 201 with no body, or with the rows. Needs create.

    • PATCH/tags/{key}{ }

      Body: a row. Changes some columns of one row.

      Answers 204, or 200 with the row. Needs update and a key.

    • DELETE/tags/{key}

      Deletes one row.

      Answers 204, or 200 with the row. Needs delete and a key.

    • PATCH/tags?filters{ }

      Body: a row. Changes every row the filters match. At least one filter is required.

      Answers 405 method_not_allowed. Needs update and bulk.

    • DELETE/tags?filters

      Deletes every row the filters match. At least one filter is required.

      Answers 405 method_not_allowed. Needs delete and bulk.

    POST /tags
    
    [{ "id": 4, "name": "later" }, { "id": 5, "name": "garden" }]

    Asking the database...

    DELETE /tags?name=eq.garden

    Asking the database...

    /steps

    write: {create: true, update: true, delete: true, bulk: true}

    • GET/steps

      Reads a page of rows; filters, embeds, order and limit apply.

      Answers 200 and an array. Needs nothing more.

    • GET/steps/{key}

      Reads one row by its key.

      Answers 200 and an object, or 404 when there is no such row. Needs a primary key.

    • POST/steps{ }

      Body: a row. Creates one row.

      Answers 201 with no body, or with the row. Needs create.

    • POST/steps[ ]

      Body: an array of rows. Creates several rows in one statement: all of them, or none if one is refused. Up to 1000 by default.

      Answers 201 with no body, or with the rows. Needs create.

    • PATCH/steps/{key}{ }

      Body: a row. Changes some columns of one row.

      Answers 204, or 200 with the row. Needs update and a key.

    • DELETE/steps/{key}

      Deletes one row.

      Answers 204, or 200 with the row. Needs delete and a key.

    • PATCH/steps?filters{ }

      Body: a row. Changes every row the filters match. At least one filter is required.

      Answers 204, or 200 with the rows. Needs update and bulk.

    • DELETE/steps?filters

      Deletes every row the filters match. At least one filter is required.

      Answers 204, or 200 with the rows. Needs delete and bulk.

    DELETE /steps?priority=lt.3&select=title
    Prefer: return=representation

    Asking the database...

    DELETE /steps

    Asking the database...

    PreviousGetting startedNext Compared with PostgREST
    restloom - a REST API generated from your database catalog
    DocumentationDownloadSource