Policies
A policy is a stateless D struct that defines how a Crate!T is exposed over the wire. It controls routing (which HTTP method and path), serialization (how JSON is formatted), and response behavior (status codes, headers, MIME types).
You define your data model once, then pick a policy — or several — to decide how clients access it.
Built-In Policies
Section titled “Built-In Policies”| Policy | Protocol | Routing | Default Path |
|---|---|---|---|
| RestApi | JSON over HTTP | Path-based | /models/:id |
| JsonApi | JSON:API | Path-based | /models/:id |
| Mcp | Model Context Protocol | Body-matched | /mcp |
| GraphQL | GraphQL | Body-matched | /graphql |
Using a Policy
Section titled “Using a Policy”Pass a policy as a template parameter to crateSetup:
auto crateRouter = router.crateSetup!RestApi;crateRouter.add(productCrate);Combining Policies
Section titled “Combining Policies”Pass multiple policies to serve the same model over multiple protocols simultaneously:
auto crateRouter = router.crateSetup!(RestApi, Mcp);crateRouter.add(productCrate);
// Product is now accessible via:// GET /products (REST)// POST /mcp (MCP: tools/call, name: "list_products")All four at once:
auto crateRouter = router.crateSetup!(RestApi, JsonApi, Mcp, GraphQL);crateRouter.add(productCrate);Selecting policies per model
Section titled “Selecting policies per model”Not every model needs every protocol. Use prepareFor to pick which policies apply:
auto crateRouter = router.crateSetup!(RestApi, Mcp, GraphQL);
// Spaces get all three protocolscrateRouter.add(spaceCrate);
// Users only get RESTcrateRouter.prepareFor!(RestApi)(userCrate) .and(authMiddleware);
// Products get REST + MCP but no GraphQLcrateRouter.prepareFor!(RestApi, Mcp)(productCrate) .and(validationFilter);Selecting a policy that is not configured on the router is a compile error.
Swapping Policies
Section titled “Swapping Policies”Switching from one protocol to another is a one-line template change:
// Before: RESTauto crateRouter = router.crateSetup!RestApi;
// After: JSON:APIauto crateRouter = router.crateSetup!JsonApi;
// Everything else stays the samecrateRouter.add(productCrate);The Crate!T, middleware, and custom operations are protocol-agnostic. Only the policy changes.
Custom Base URLs
Section titled “Custom Base URLs”Each policy accepts a PolicyConfig for base URL customization:
auto crateRouter = router.crateSetup!( RestApiPolicy!(PolicyConfig("/api/v1")), McpPolicy!(PolicyConfig("/tools")), GraphQLPolicy!(PolicyConfig("/api")));crateRouter.add(productCrate);
// REST: GET /api/v1/products// MCP: POST /tools/mcp// GraphQL: POST /api/graphqlCreating Your Own
Section titled “Creating Your Own”See Creating a Custom Policy for how to implement a new protocol.