Views
A view is a filtered subset of a collection. Unlike traditional database views, RestAPI.com views are fully updatable — you can create, update, and delete items through a view.
What Views Do
- Filter items — Show only items matching criteria
- Limit properties — Expose only selected fields
- Control access — Use with security rules for fine-grained permissions
- Full CRUD support — Create, read, update, and delete through views
URL Structure
Views share the same namespace as collections:
/api/{view-name}
For external clients, replace /api with https://<region>.restapi.com/<api-name>. See Virtual Paths.
Creating a View
- Open the Developer Portal
- Navigate to your API's schema
- Create a new view
- Select the base collection
- Configure filter and properties
Filtering
Apply a filter to show only matching items:
| Filter | Result |
|---|---|
itemsInStock eq 0 | Out of stock items only |
status eq "active" | Active items only |
price lt 100 | Items under $100 |
Filter Operators
| Operator | Description | Example |
|---|---|---|
eq | Equal to | status eq "active" |
ne | Not equal to | status ne "deleted" |
gt | Greater than | price gt 100 |
lt | Less than | stock lt 10 |
ge | Greater than or equal | rating ge 4 |
le | Less than or equal | priority le 3 |
con | Contains (strings) | name con "pro" |
ncon | Not contains | name ncon "test" |
sw | Starts with | name sw "Pro" |
ew | Ends with | name ew "Plus" |
Case-insensitive: Append ~ to operators (e.g., eq~, con~)
Combine conditions: Use and, or, and parentheses:
status eq "active" and (priority eq "high" or priority eq "urgent")
Dynamic Expressions
Use exp() for dynamic values in filters. The expression must be wrapped in single or double quotes.
When using + in URLs, encode it as %2B (e.g., exp('now() %2B 7D')).
created gt exp('now() - 30D') # Items from last 30 days
expiresAt lt exp('now()') # Expired items
dueDate le exp('now() + 7D') # Due within a week
Date/time tokens:
| Token | Description | Example |
|---|---|---|
now() | Current UTC date-time | now() |
D | Days | now() + 7D |
H | Hours | now() + 24H |
M | Minutes | now() + 30M |
S | Seconds | now() + 60S |
Tokens are case-insensitive. All date/time values are handled in UTC.
Current user: userId() resolves to the id of the authenticated caller, which
is what a per-user view filters on (owner eq userId()). It is a function call
like now() — there is no {{...}} placeholder syntax.
Example
Base collection (products):
| SKU | Name | Price | Stock |
|---|---|---|---|
| A1 | Widget A | 29.99 | 10 |
| B2 | Widget B | 19.99 | 0 |
| C3 | Widget C | 39.99 | 5 |
| D4 | Widget D | 24.99 | 0 |
View with filter stock eq 0:
| SKU | Name | Price |
|---|---|---|
| B2 | Widget B | 19.99 |
| D4 | Widget D | 24.99 |
Selecting Properties
Choose which properties to include in the view:
- Include all properties from the base collection
- Select a subset of properties
Omitting properties hides them from API consumers.
Updatable Views
Views support all HTTP methods just like collections:
| Method | Description |
|---|---|
GET | Read items matching the view filter |
POST | Create new items (must match view filter) |
PUT | Replace items within the view |
PATCH | Update items within the view |
DELETE | Delete items within the view |
When creating items through a view, the new item must satisfy the view's filter criteria.
View vs Collection
| Feature | Collection | View |
|---|---|---|
| Store data | Yes | No (references collection) |
| Create items | Yes | Yes |
| Update items | Yes | Yes |
| Delete items | Yes | Yes |
| Filter data | Via query params | Built-in filter |
| Independent access rules | Yes | Yes |
Use Cases
Public API
Expose a view with limited fields for public access:
products-public → Shows: name, description, price
products (internal) → Shows: all fields including cost, supplier
Status-Based Access
Create views for different item states:
orders-pending → filter: status eq "pending"
orders-shipped → filter: status eq "shipped"
orders-completed → filter: status eq "completed"
Role-Based Data
Combine views with security rules:
my-orders → filter: owner eq userId()
Security
A view's filter is enforced on the server for reads, and for element-targeted
PATCH and PUT: a write aimed at a row outside the filter is refused with 400
and Not found, so a caller with update access to my-orders cannot reach another
user's row in the underlying collection by addressing it by id.
DELETE is not filtered by the viewA DELETE through a view resolves to the base collection before any filter is
evaluated, so the view's filter does not constrain it — only _CREATOR and
security policies do. A caller granted DELETE
on a filtered view can delete any row of the base collection by id, including
rows the view would never show them. Grant DELETE on a view only where deleting
any row of the collection is acceptable, or back the view with a security policy
covering the same rows.
The filter constrains callers of the view. A view and its base collection are
separate entities with their own access rules, and
the collection is still served at its own path — anyone holding that method on the
collection reads it without the view's filter (the collection's own _CREATOR and
security policies still apply). A view narrows what a caller sees through it; it
takes nothing away from the collection. If the rows are meant to be private,
restrict the collection as well, or don't grant the method there at all.
Views work with the other row-level controls too:
- Security policies apply to a view just as
they do to its collection. An entity with a resolved security-policy path never
serves anonymous callers: a request without a token is rejected with
401, even where_EVERYONEis named on the method. _CREATORfilters a view to the caller's own rows, matching on the base collection'screatedBy. See Owner-Only Access for its limits.