Skip to main content
Use a resource when the client should read data instead of asking the server to perform an action. Resources are a better fit than tools when the thing you are exposing has a stable identity and should be addressed by URI. This page focuses on when resources fit and how to model them well. For the exact resource contract, use Resource Definition.

When a resource is the right fit

Use a resource when:
  • the client needs readable data
  • the data has a stable URI
  • subscriptions or change notifications make sense
Avoid a resource when the caller is really triggering business logic, a workflow, or a state-changing action. That is a tool.

Static and template resources

Redop supports two resource styles:
  • static resources such as config://server
  • template resources such as users://{id}/profile
Choose a static resource when one URI maps to one stable document. Choose a template resource when many concrete URIs share the same shape.

Static resource example

Model the URI carefully

Resources have two identifiers:
  • the URI, which clients use to address the resource
  • the name, which is the human-readable display label
The URI matters most because it is the stable address clients call. Prefer URI shapes that reflect the data model cleanly. Good examples:
  • config://server
  • notes://latest
  • users://{id}/profile

Description and MIME type

Use description to explain what the resource represents. Use mimeType to describe the content clients should expect back.

Template resource example

Redop infers template params from the URI you register. In a resource like users://{id}/profile, the handler receives params.id as a string.

What resource handlers return

Return one of these shapes:
  • { type: "text", text, mimeType? } for UTF-8 content
  • { type: "blob", blob, mimeType? } for base64-encoded binary content
That return contract stays small on purpose. The main design work is usually choosing the URI and deciding whether the content is stable enough to behave like a resource.

Local hooks and middleware

Resources support per-resource execution logic:
  • before runs before middleware and the handler
  • after runs after a successful result and may replace it
  • afterResponse runs after the response is written and cannot replace it
  • middleware wraps only that resource
Use afterResponse for non-critical follow-up work such as logging, metrics, or audit events.

Use subscriptions when the data changes

If clients should be notified when a resource changes:
  • set subscribe: true on the resource
  • call notifyResourceChanged(uri) when the underlying data changes
Use subscriptions when the resource identity stays stable but the underlying content changes over time.