CRUD Generation
Note
The
deleteoperation is not currently supported, but will be added in a future release.
Creating the same CRUD operations for each Model can be tedious. Cloesce provides a way to automatically generate these operations based on your Model definitions and Data Source configurations.
For every public Data Source defined on a Model, Cloesce will utilize the get, save, and list methods of that Data Source to generate CRUD API endpoints for that Model.
Get
By default, the get operation retrieves a single record by its primary key, shard fields and route fields. For example:
[crud get]
model Person for PersonDo(tenant) {
primary {
id: int
}
}
source Custom for Person {
get(special_id: int)
}
The above schema will generate two API methods:
-
GET /Person/$get: Accepts argumentstenantandid, hydrates with the Default Data Source, and returns aPersoninstance if a record is found -
GET /Person/$get_Custom: Accepts argumentspecial_id, hydrates with the Custom Data Source, and returns aPersoninstance if a record is found
List
Important
The
listoperation can only be used if your Model does not have any route fields.
The list operation retrieves multiple records. By default, it will use a seek based pagination strategy. For example:
[crud list]
model Person for Db {
primary {
id: int
}
}
source OffsetPagination for Person {
list(offset: int, limit: int)
}
The above schema will generate two API methods:
-
GET /Person/$list: Accepts argumentslimitandlastSeen_id, hydrates with the Default Data Source, and returns a paginated list ofPersoninstances -
GET /Person/$list_OffsetPagination: Accepts argumentsoffsetandlimit, hydrates with the Custom Data Source, and returns a paginated list ofPersoninstances
Save
The save operation creates or updates any record within a Data Source’s include tree.
The only parameter save accepts is a partial Model instance, which is an object that may contain a subset of the Model’s fields. For example:
[crud save]
model Person for Db {
primary {
id: int
}
}
The client could then invoke a method like:
export class Person {
// ...
static async $save(model: DeepPartial<Person>): Promise<HttpResult<Person>> {
// ...
}
}
const result = await Person.$save({
id: 1,
name: "Alice",
});
R2 Fields
If your Model contains an R2 field, the save operation will not be able to accept any data for that field, since the ORM is designed only for JSON serializable data. To work around this, you can define a custom instance method on your Model that accepts a stream parameter:
model Person {
route {
id: int
}
r2 Bucket::photos(id) {
avatar
}
}
api Person {
[inject Bucket]
post upload_photo(self, photo: stream)
}
import * as clo from "@cloesce/backend.js";
export const Person = clo.Person.impl({
async upload_photo(self, env, photo) {
await env.Bucket.photos.put(photo);
},
});