1 unstable release
Uses old Rust 2015
0.1.0 | Oct 31, 2018 |
---|
#64 in #json-api
18KB
255 lines
Breadboard 🍞🛹
Breadboard is a simple JSON API request router for hyper.
Perhaps it will become less simple later.
It is in early development but you might find it useful. Your feedback is welcomed.
lib.rs
:
Breadboard is a simple JSON API request router for hyper.
Like electronics breadboards, Breadboard is well-suited to prototyping your API. Also like electronics breadboards, its functionality is limited and if you bend it too hard it will snap.
To create a hyper Service
, create a Breadboard
with Breadboard::new
, use methods like
Breadboard::get
to add handlers, then use it in hyper::server::Builder::serve
.
Quick start
extern crate breadboard;
extern crate hyper;
use breadboard::Breadboard;
use hyper::server::Server;
use hyper::{Request, Response};
use std::string::ParseError; // waiting for `!`
fn hello(_: Request<()>) -> Result<Response<&'static str>, ParseError> {
Ok(Response::new("Hello, world!"))
}
let board = Breadboard::new().get("/", hello);
let server = Server::bind(&"127.0.0.1:3000".parse().unwrap())
.serve(board);
// hyper::rt::run(server.map_err(|e| eprintln!("server error: {}", e)));
You can also use closures as handlers:
let board = Breadboard::new().get(
"/",
|_: Request<()>| -> Result<Response<&'static str>, ParseError> {
Ok(Response::new("Hello, world!"))
},
);
let server = Server::bind(&"127.0.0.1:3000".parse().unwrap())
.serve(board);
Handlers that return Futures
Handlers return a type that implement IntoFuture
. This includes Result
, as well as all
types that implement Future
.
This example handler makes an HTTP request and responds with the response it receives. It
returns a Future
that resolves after the request completes.
extern crate breadboard;
extern crate hyper;
use breadboard::Breadboard;
use hyper::client::Client;
use hyper::rt::{Future, Stream};
use hyper::server::Server;
use hyper::{Body, Request, Response};
fn proxy(_: Request<()>) -> impl Future<Item = Response<Vec<u8>>, Error = hyper::Error> {
let client: Client<_, Body> = Client::builder().build_http();
client
.get("http://icanhazip.com/".parse().unwrap())
.and_then(|response| {
let (parts, body) = response.into_parts();
body.concat2()
.map(|chunk| Response::from_parts(parts, chunk.into_bytes().to_vec()))
})
}
let board = Breadboard::new().get("/", proxy);
let server = Server::bind(&"127.0.0.1:3000".parse().unwrap())
.serve(board);
Deserialize and Serialize
The real power of Breadboard is that request and response bodies can be anything as long as they implement Deserialize and Serialize, respectively.
extern crate breadboard;
extern crate hyper;
extern crate serde;
#[macro_use]
extern crate serde_derive;
use breadboard::Breadboard;
use hyper::client::Client;
use hyper::rt::{Future, Stream};
use hyper::server::Server;
use hyper::{Body, Request, Response};
use std::string::ParseError; // waiting for `!`
#[derive(Debug, Deserialize)]
struct Message {
message: String,
}
fn message(request: Request<Message>) -> Result<Response<String>, ParseError> {
Ok(Response::new(request.into_body().message))
}
let board = Breadboard::new().post("/", message);
let server = Server::bind(&"127.0.0.1:3000".parse().unwrap())
.serve(board);
Dependencies
~9MB
~160K SLoC