Skip to content

Getting Started

Add Crate as a dependency in your dub.json:

{
"dependencies": {
"crate": "~>1.0"
}
}

Or in dub.sdl:

dependency "crate" version="~>1.0"

Crate depends on vibe.d, which will be pulled in automatically.

A Crate model is a plain D struct with a string _id field:

struct Product {
string _id;
string name;
int price;
}

The _id field is the primary key. Crate uses it for item-level operations like GET, PUT, PATCH, and DELETE.

import crate.http.router;
import crate.collection.memory;
import vibe.http.router;
void main() {
auto router = new URLRouter();
auto products = new MemoryCrate!Product;
router.crateSetup!RestApi.add(products);
router.run();
}

Start your application and use curl to interact with the API:

Terminal window
# Create a product
curl -X POST http://localhost:8080/products \
-H "Content-Type: application/json" \
-d '{"product": {"name": "Widget", "price": 42}}'
# List all products
curl http://localhost:8080/products
# Get a specific product
curl http://localhost:8080/products/000000000000000000000001
# Update a product
curl -X PATCH http://localhost:8080/products/000000000000000000000001 \
-H "Content-Type: application/json" \
-d '{"product": {"price": 50}}'
# Replace a product
curl -X PUT http://localhost:8080/products/000000000000000000000001 \
-H "Content-Type: application/json" \
-d '{"product": {"name": "Super Widget", "price": 99}}'
# Delete a product
curl -X DELETE http://localhost:8080/products/000000000000000000000001

Notice the request body wraps the data in a key matching the model name ("product"). The REST API policy uses this convention for both requests and responses.

For production, replace MemoryCrate with MongoCrate:

import crate.collection.mongo;
auto products = new MongoCrate!Product("products_collection");

The MongoCrate constructor takes the MongoDB collection name. It uses the same interface as MemoryCrate, so the rest of your code stays the same.

Crate automatically generates route paths from your struct name:

Struct NameList PathItem Path
Product/products/products/:id
User/users/users/:id
MapFile/mapfiles/mapfiles/:id
SiteSubset/sitesubsets/sitesubsets/:id

The path is the struct name lowercased with an “s” appended.

Chain multiple add() calls on the same router:

auto crateRouter = router.crateSetup!RestApi;
crateRouter.add(productCrate);
crateRouter.add(userCrate);
crateRouter.add(orderCrate);

Or use prepare() for models that need custom configuration:

crateRouter.add(productCrate); // Simple model
crateRouter
.prepare(userCrate) // Complex model
.and(authMiddleware)
.and(validationFilter);