Crate breadboard

source ·
Expand description

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);

Structs

A router builder.
The hyper Service.

Enums

An error when creating the Service from a Breadboard.
An error during request handling.