json-api

Idiomatic types for building a robust JSON API.
⚠️ Warning
This crate is under active development. Some features have yet to be implemented,
APIs are likely to change, and documentation is sparse.
Consider this alpha quality software until this warning is removed.
Features
Serialization DSL
You can define a Resource
using a friendly, declarative dsl.
Concise
pub struct Article {
pub id: u64,
pub body: String,
pub title: String,
pub author: User,
pub comments: Vec<Comment>,
}
resource!(Article, |&self| {
id self.id.to_string();
kind "articles";
attrs body, title;
has_one author;
has_many comments;
});
Flexible
pub struct Article {
pub id: u64,
pub body: String,
pub title: String,
pub author: User,
pub comments: Vec<Comment>,
}
resource!(Article, |&self| {
id self.id.to_string();
kind "articles";
attrs body, title;
attr "preview", {
self.body
.iter()
.cloned()
.take(140)
.collect::<String>()
}
has_one "author", {
data Some(&self.author);
link "self", format!("/articles/{}/relationships/author", self.id);
link "related", format!("/articles/{}/author", self.id);
meta "read-only", true
}
has_many "comments", {
data self.comments.iter();
link "self", format!("/articles/{}/relationships/comments", self.id);
link "related", format!("/articles/{}/comments", self.id);
meta "total", {
self.comments.len()
}
}
link "self", {
href format!("/articles/{}", self.id);
}
meta "copyright", {
format!("© 2017 {}", self.author.full_name())
}
});
Rocket Support
The json-api-rocket crate provides responders
as well as a fairing for catching errors and returning JSON API
error documents.
#![feature(plugin)]
#![plugin(rocket_codegen)]
#[macro_use]
extern crate json_api;
extern crate json_api_rocket;
extern crate rocket;
mod models;
use json_api_rocket::JsonApiFairing;
use json_api_rocket::response::{Collection, Member};
use models::Article;
#[get("/")]
fn collection() -> Collection<Article> {
(1..25).map(Article::new).collect()
}
#[get("/<id>")]
fn member(id: u64) -> Member<Article> {
Member(Article::new(id))
}
fn main() {
rocket::ignite()
.attach(JsonApiFairing)
.mount("/articles", routes![collection, member])
.launch();
}
License
Licensed under either of
at your option.
Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
dual licensed as above, without any additional terms or conditions.