DCE
DCE is a routing framework for all kinds of routable interfaces. Almost every application provides interactive interfaces, but because different protocols (HTTP, CLI, TCP, WebSocket, ...) have different addressing rules, there is no unified routing rule across them. That leads to chaotic program structures and makes it hard to control every interface in a unified and convenient way.
DCE solves this by providing a standard router and encapsulating the routable protocol: as long as an interface implements the RoutableProtocol trait, it can be uniformly routed through the DCE router. For protocols without a standard URI path (such as CLI or custom binary protocols), you implement the trait yourself and the router will handle them the same way as HTTP.
The router package lives in crates/router. Working protocol implementations are located in crates/protocols, converters in crates/converter, macros in crates/macro, and the session/JWT library in crates/auth.
Features
- Unified routing for every routable protocol: HTTP (
dce-hyper), CLI (dce-cli), and custom protocols. - Fast path matching: regular paths match from the API hash map in O(1); variable paths scale with the number of peer variables.
- Variable paths: required
{name}, optional{name?}, vector{name+}, emptable vector{name*}. - Suffix routing: route by file-like suffixes such as
file.txt,file.txt|json. - Omission: mark a path segment as omitable so it can be skipped during matching.
- API metadata: every API can carry an
id,name,methods,redirect, and arbitrary extra data (for docs, permissions, metrics, ...). - Global middleware: pre/post handlers can be attached to paths (including wildcard paths) for things like global permission control.
- Converters & serializers: DTO ↔ entity conversion with desensitization, plus pluggable serializers (JSON, Protobuf) for request decoding and response building.
- Macros: the
#[api]attribute macro turns any function into a routable API; error macros generate public/private error messages. - Session & JWT: user session, renewable/rotating JSON Web Token, in-memory (SHM) or Redis storage.
Workspace layout
[ROOT]
├── crates Crate directory
│ ├── macro dce-macro, attribute and error macros
│ ├── router dce-router, the core router
│ ├── converter dce-converter, JSON / Protobuf converters
│ ├── auth dce-session, session, user & JWT library
│ ├── util dce-util, shared utilities
│ └── protocols Routable protocol implementations
│ ├── cli dce-cli, CLI routable protocol
│ └── hyper dce-hyper, HTTP routable protocol
├── examples Runnable example binaries
│ ├── async-http.rs Async HTTP + CLI example
│ └── sync-http.rs HTTP example with sync handlers
└── src Reserved for the DCE command line tools
The src directory is reserved for DCE command line tools that are planned to live in this repository, so it currently only contains an empty library root.
Getting started
Add the crates you need to your Cargo.toml:
[]
= { = "crates/router", = "^1.8" }
= { = "crates/macro", = "1.*" }
= { = "crates/util", = "^1.8" }
= { = "crates/protocols/cli", = "^1.8" }
= { = "^1.49", = ["full"] }
Define APIs with the #[api] macro, register them on the router, then route incoming requests:
use ;
use api;
use Request;
use DceVoid;
async
/// cargo run -- hello
/// cargo run -- hello --target DCE
async
The #[api] macro generates a fn <name>_api() -> Api<Rp> supplier for every annotated function, which is then fed to the router through Router::register. Alternatively you can build an Api manually and use Router::bind, Router::bind_api, or the convenient HttpRouter::get/post/... methods.
HTTP example
use ;
use ;
use api;
use Request;
use DceVoid;
HyperRouter.write.await
.register
.register
.ready;
// serve any `hyper::Request` via `hyper_route`
// hyper1::Builder::new().serve_connection(io, service_fn(|req| hyper_route(req, Default::default())))
/// curl http://127.0.0.1:2046/hello
async
/// curl -X POST http://127.0.0.1:2046/hello -H "Content-Type: application/json" -d '{"user":"Drunk","age":18}'
async
Run the full runnable examples:
Routing rules
The path grammar mirrors a URI but is shared by every protocol:
| Syntax | Meaning |
|---|---|
hello |
fixed segment |
{name} |
required variable segment |
{name?} |
optional variable segment (only at the end) |
{name+} |
vector of one or more segments |
{name*} |
vector of zero or more segments |
file.txt |
suffix routing |
file.txt|json |
multiple suffixes |
omission = true |
the segment may be omitted during matching |
Note: optional (?) and vector (+/*) variables are only allowed at the end of a path, because an ambiguous variable in the middle cannot be resolved unambiguously.
APIs are matched by path first; when several APIs share a path, RoutableProtocol::match_api (for HTTP, method and host matching) selects the final one. A matched API may also redirect to another path, so legacy routes can forward transparently.
Converters & serializers
The RequestDecoder and ResponseBuilder types in dce-router decouple request/response payloads from your business types:
- Deserializer decodes raw bytes into a request DTO.
- Serializer encodes a response DTO into raw bytes.
- Status renders the unified
{status, code, msg, data}response envelope.
dce-converter ships JSON and Protobuf implementations. Because the mapping between DTO and entity is done through the standard From/Into traits, you can freely desensitize or reshape entity data before it is transmitted.
Session & JWT
The session library provides basic session storage, user sessions, long-lived connection sessions, and self-regenerating (rotating) sessions, so user-level permission control plugs cleanly into the router. The JWT implementation supports HS256/384/512 signing and rotation.
Performance
Because the process chain is very short — the router calls the controller directly after matching the API by path — performance is very high. Regular paths are matched from the API hash map in O(1); a single-variable path costs O(n); multiple variables scale exponentially with the number of peer variables. Prefer regular paths, or keep the number of variables and peer variables small, to get the best routing performance.
License
MIT