Crate webmachine
source · [−]Expand description
webmachine-rust
Port of Webmachine-Ruby https://github.com/webmachine/webmachine-ruby to Rust.
webmachine-rust is a port of the Ruby version of webmachine. It implements a finite state machine for the HTTP protocol that provides semantic HTTP handling (based on the diagram from the webmachine project). It is basically a HTTP toolkit for building HTTP-friendly applications using the Hyper rust crate.
Webmachine-rust works with Hyper and sits between the Hyper Handler and your application code. It provides a resource struct with callbacks to handle the decisions required as the state machine is executed against the request with the following sequence.
REQUEST -> Hyper Handler -> WebmachineDispatcher -> WebmachineResource -> Your application code -> WebmachineResponse -> Hyper -> RESPONSE
Features
- Handles the hard parts of content negotiation, conditional requests, and response codes for you.
- Provides a resource struct with points of extension to let you describe what is relevant about your particular resource.
Missing Features
Currently, the following features from webmachine-ruby have not been implemented:
- Visual debugger
- Streaming response bodies
Implementation Deficiencies:
This implementation has the following deficiencies:
- Automatically decoding request bodies and encoding response bodies.
- No easy mechanism to generate bodies with different content types (e.g. JSON vs. XML).
- No easy mechanism for handling sub-paths in a resource.
- Dynamically determining the methods allowed on the resource.
Getting started with Hyper
Follow the getting started documentation from the Hyper crate to setup a Hyper service for your server.
You need to define a WebmachineDispatcher that maps resource paths to your webmachine resources (WebmachineResource).
Each WebmachineResource defines all the callbacks (via Closures) and values required to implement a resource.
The WebmachineDispatcher implementes the Hyper Service trait, so you can pass it to the make_service_fn
.
Note: This example uses the maplit crate to provide the btreemap
macro and the log crate for the logging macros.
use webmachine::*;
use webmachine::{context::*, headers::*};
use serde_json::{Value, json};
use hyper::{server::Server, service::make_service_fn};
use std::{io::Read, net::SocketAddr, convert::Infallible};
// setup the dispatcher, which maps paths to resources. The requirement of make_service_fn is
// that it has a static lifetime
fn dispatcher() -> Dispatcher<'static> {
Dispatcher {
routes: btreemap!{
"/myresource" => Resource {
// Methods allowed on this resource
allowed_methods: vec!["OPTIONS", "GET", "HEAD", "POST"],
// if the resource exists callback
resource_exists: callback(&|_, _| Box::pin(async { true })),
// callback to render the response for the resource
render_response: callback(&|_, _| Box::pin(async {
let json_response = json!({
"data": [1, 2, 3, 4]
});
Some(json_response.to_string())
})),
// callback to process the post for the resource
process_post: callback(&|_, _| Box::pin(async {
// Handle the post here
Ok(true)
})),
// default everything else
.. Resource::default()
}
}
}
}
async fn start_server() -> Result<(), String> {
// Create a Hyper server that delegates to the dispatcher
let addr = "0.0.0.0:8080".parse().unwrap();
let make_svc = make_service_fn(|_| async { Ok::<_, Infallible>(dispatcher()) });
match Server::try_bind(&addr) {
Ok(server) => {
// start the actual server
server.serve(make_svc).await;
},
Err(err) => {
error!("could not start server: {}", err);
}
};
Ok(())
}
Example implementations
For an example of a project using this crate, have a look at the Pact Mock Server from the Pact reference implementation.
Modules
The cache
module declare the cache functionality for webmachine is
executing in. Basically implements in-memory and Dummy cache.
Inspired by any-cache.
The content_negotiation
module deals with handling media types, languages, charsets and
encodings as per https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html.
The context
module encapsulates the context of the environment that the webmachine is
executing in. Basically wraps the request and response.
The headers
deals with parsing and formatting request and response headers
Wamp(v2) support
Macros
Simple macro to convert a string to a HeaderValue
struct.
Structs
The main hyper dispatcher
Struct to represent a resource in webmachine
Functions
Wrap a callback in a structure that is safe to call between threads
Type Definitions
Type of a Webmachine resource callback