Skip to main content

Crate roas_http_validator

Crate roas_http_validator 

Source
Expand description

Validates HTTP requests against an OpenAPI description.

roas parses a description and checks that the description is well formed. This checks that a request is what the description says it should be: the path is one the description names, the method is one that path offers, every required parameter arrived, each one is the type its Schema Object declares, and the body is what the Request Body Object describes.

use roas_http_validator::{RequestView, Validator};

let validator = Validator::new(spec);

let request = RequestView::new("GET", "/pets").with_query("limit=1000");
let report = validator.validate(&request)?;

assert!(!report.is_valid());
assert_eq!(
    report.errors[0].to_string(),
    "query parameter \"limit\": 1000 is above maximum 100",
);

§Examples

The repository carries three runnable ones: validate for the shape of the whole crate, axum_layer for the same thing as middleware (and for what buffering a body actually looks like), and client_check for asking whether a call you are about to make matches the description.

§Which request type

None of them, and all of them. Rust has no single HTTP request type to validate: http::Request comes closest, but it is generic over a body that is usually a stream, and it is version-split — actix-web 4 is on http 0.2 while hyper 1, axum 0.8 and reqwest are on 1.x, so their HeaderMaps are different types. Taking either one would shut out half the ecosystem.

So this crate takes RequestView, the small set of things an OpenAPI description actually talks about, and each framework gets a ToRequestView impl behind its own feature:

FeatureCovers
httphttp::Request, http::request::Parts — and so axum, warp, tonic, hyper
actix-webactix_web::HttpRequest
poempoem::Request
salvosalvo_core::http::Request
rocketrocket::Request
reqwestreqwest::Request and its blocking twin — the client’s side, for checking an outgoing call

The body is not part of that conversion. A framework body is a stream, and validating one means buffering it — how much, and whether at all, is the caller’s decision, so the adapters convert the head and RequestView::with_body takes the bytes. The one exception is reqwest, where a non-streaming body is already bytes in memory and there is nothing to buffer.

§Versions

The interpreter is v3.2. Enable v3_1, v3_0 or v2 to accept a description written to an older version: it is upconverted through roas’s own migrations first, so there is one interpreter rather than four.

§What it does not do yet

Response validation, security requirements, multipart/form-data bodies, and XML — and exact decimal arithmetic, which would need serde_json’s arbitrary_precision: numbers are compared as the IEEE-754 doubles they arrive as, and anything that would over-claim on top of one is reported rather than assumed. Anything a check could not judge is reported — split out by ValidationReport::unchecked from what the request definitely got wrong — ErrorKind::Unsupported for what is not implemented yet, ErrorKind::Unchecked for a description this crate can read but cannot apply faithfully — rather than passed over, so a request never looks valid because nothing looked at it.

Structs§

Options
What to check, and where the description’s paths start.
RequestView
One HTTP request, as much of it as an OpenAPI description describes.
ValidationError
One thing wrong with the request.
ValidationReport
The verdict on one request that the description does describe.
Validator
One OpenAPI description, ready to judge requests against.

Enums§

ErrorKind
What was wrong with one parameter or with the body.
Location
Where in the request an error was found.
RoutingError
The description does not describe this request at all.

Traits§

ToRequestView
A framework’s own request type, seen as a RequestView.