Entities & Relations
Your data model in Pylo is a set of entities with typed fields and relations between them. You define both in the admin panel under Settings > Entities. Pylo generates the API from this model: every entity gets a list query, a by-ID query, and create/update/delete mutations.
Fields
Every field has a data type. The API represents each one as a GraphQL scalar:
| Data type | GraphQL type |
|---|---|
text | String |
longtext | String |
richtext | String |
int | Int |
float | Float |
boolean | Boolean |
date | String |
time | String |
datetime | String |
json | String |
enum | generated enum |
date, time, and datetime values are ISO 8601 strings. Pylo serializes json values as
strings. An enum field generates a GraphQL enum from its configured values.
Every entity also carries system fields:
| Field | Type | Description |
|---|---|---|
id | ID | Unique identifier (UUID) |
integer_id | Int | Auto-incrementing ID |
created_at | String | Creation timestamp (ISO 8601 datetime) |
updated_at | String | Last update timestamp (ISO 8601 datetime) |
Relations
A relation connects two entities. In the relation settings you give each side a field name, and
an entity only exposes the relation if its side has one. A relation between order and customer
with both field names set adds customer to orders and orders to customers. Leave one side empty
and that entity does not show the relation at all.
The cardinality determines the query shape:
- hasOne (ManyToOne, OneToOne):
{ data: { ... } } | null - hasMany (OneToMany, ManyToMany):
{ data: [...], pagination }
Relation writes are fields on the entity's update input. In the SDKs, _set, _connect, and
_disconnect go through the same upsert call as any field change, so you can combine them with
field updates in one mutation. Set a hasOne relation with _set:
1
2
3
4
5
6
import { pylo } from './lib/pylo';
await pylo.order.upsert({
id: 'order-uuid',
customer_set: { id: 'customer-uuid' },
});For hasMany relations, _connect adds records, _disconnect removes them, and _set replaces the
whole list:
1
2
3
4
5
6
7
import { pylo } from './lib/pylo';
await pylo.customer.upsert({
id: 'customer-uuid',
orders_connect: [{ id: 'order-uuid' }],
orders_disconnect: [{ id: 'old-order-uuid' }],
});Relations to system entities (for example PyloMedia) use _add / _remove instead of _connect
/ _disconnect. Besides ids, __search_value targets records by field, including inside nested
relation upserts. See Mutations.
Relations point at your own entities or at system entities. A relation to PyloMedia attaches
file uploads to your records.
System entities
Pylo ships built-in entities that follow the same API patterns as your own:
| Entity | Purpose |
|---|---|
PyloUser | User accounts and authentication |
PyloMedia | Files and media uploads |
PyloApiKey | API tokens for programmatic access |
PyloApp | Application configuration |