Skip to content

Crates

A crate is a storage backend that implements the Crate!T interface. It defines how data is stored and retrieved — in memory, in MongoDB, from a CSV file, or anywhere else. The framework uses the crate to execute CRUD operations; everything above (routing, middleware, serialization) is handled by the policy and middleware layers.

Every crate implements Crate!T, which extends CrateAccess:

interface CrateAccess {
@safe:
IQuery get(); // Query over all items
IQuery getItem(const string id); // Query for one item by ID
Json addItem(const Json item); // Insert, return with generated ID
Json updateItem(const Json item); // Replace by ID, return updated
void deleteItem(const string id); // Remove by ID
}
interface Crate(Type) : CrateAccess {
}
CrateBackendUse Case
MemoryCrateIn-memory arrayTesting, prototyping
MongoCrateMongoDBProduction databases
CrateCacheDecoratorCaching layer over any crate
CsvCrateCSV fileFlat data import/export

Create an instance and add it to a router:

auto products = new MemoryCrate!Product;
router.crateSetup!RestApi.add(products);

The framework only cares that your crate implements Crate!T. Routing, middleware, serialization — all handled automatically.

Crate’s get() and getItem() methods return IQuery, the query builder that operations use for filtering, sorting, and pagination:

interface IQuery {
@safe:
IFieldQuery where(string field);
IQuery sort(string field, int order); // 1 = ascending, -1 = descending
IQuery limit(size_t nr);
IQuery skip(size_t nr);
InputRange!Json exec(); // Execute and stream results
size_t size(); // Count without fetching
}

where() returns IFieldQuery for building conditions:

auto results = crate.get()
.where("status").equal("active").and()
.where("score").greaterThan(threshold).and()
.sort("name", 1)
.limit(20)
.exec();

Every crate accepts a CrateConfig!T that lets you disable specific operations:

auto config = CrateConfig!Product();
config.deleteItem = false; // No DELETE endpoint generated
auto products = new MongoCrate!Product(collection, config);

See Creating a Custom Crate for how to implement a new storage backend.