json-api
Idiomatic types for building a robust JSON API.
Features
Serialization DSL
You can define a Resource
using a friendly, declarative dsl.
Concise
#[macro_use]
extern crate json_api;
struct Post {
id: u64,
body: String,
title: String,
author: Option<User>,
comments: Vec<Comment>,
}
resource!(Post, |&self| {
id self.id;
kind "posts";
attrs body, title;
has_one author;
has_many comments;
});
Flexible
#[macro_use]
extern crate json_api;
struct Post {
id: u64,
body: String,
title: String,
author: Option<User>,
comments: Vec<Comment>,
}
resource!(Post, |&self| {
kind "articles";
id self.id;
attrs body, title;
attr "preview", {
self.body
.chars()
.take(140)
.collect::<String>()
}
has_one "author", {
data self.author.as_ref();
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", self.author.as_ref().map(|user| {
format!("© 2017 {}", user.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.