1 unstable release
| 0.1.0 | Feb 23, 2026 |
|---|
#2362 in Parser implementations
Used in 2 crates
59KB
1K
SLoC
openapi-deref
Lightweight OpenAPI / JSON Schema $ref resolver for Rust.
Recursively expands all $ref pointers in a serde_json::Value, producing a self-contained document with no unresolved references.
Features
- Resolves internal
$refvia JSON Pointer (RFC 6901) - OpenAPI 3.1 compatible: sibling keys alongside
$refare merged - Cycle detection with a visited-path set
- Typed error model: fatal
ResolveErrorvs non-fatalRefError resolve_strictfor zero-tolerance mode- Diagnostics: inspect cycles, missing refs, and external refs individually
- Zero dependencies beyond
serde_jsonandthiserror
Quick start
use serde_json::json;
let value = openapi_deref::resolve_strict(&json!({
"components": { "schemas": { "Id": { "type": "integer" } } },
"field": { "$ref": "#/components/schemas/Id" }
})).unwrap();
assert_eq!(value["field"]["type"], "integer");
API levels
| Function | Returns | Use when |
|---|---|---|
resolve_strict |
Result<Value, StrictResolveError> |
Any unresolved ref is unacceptable |
resolve |
Result<ResolvedDoc, ResolveError> |
You need to inspect partial results or diagnostics |
resolve_with_root |
Result<ResolvedDoc, ResolveError> |
The ref lookup root differs from the target value |
Error handling
Non-fatal ref errors are collected in ResolvedDoc and can be inspected:
use serde_json::json;
use openapi_deref::resolve;
let spec = json!({
"components": { "schemas": {
"Node": { "properties": { "child": { "$ref": "#/components/schemas/Node" } } }
}},
"root": { "$ref": "#/components/schemas/Node" }
});
let doc = resolve(&spec).unwrap();
assert_eq!(doc.cycles().count(), 1);
assert_eq!(doc.missing_refs().count(), 0);
assert_eq!(doc.external_refs().count(), 0);
License
Licensed under either of
- MIT license (LICENSE-MIT)
- Apache License, Version 2.0 (LICENSE-APACHE)
at your option.
Dependencies
~0.4–1.2MB
~24K SLoC