Idiomatic types for building a robust JSON API.
You can define a Resource
using a friendly, declarative dsl.
```rust
pub struct Article {
pub id: u64,
pub body: String,
pub title: String,
pub author: User,
pub comments: Vec
resource!(Article, |&self| { // Define the id with an expression that returns a string. id self.id.to_string();
// Define the resource "type"
kind "articles";
// Define attributes with a comma seperated list of field names.
attrs body, title;
// Define relationships with a comma seperated list of field names.
has_one author;
has_many comments;
}); ```
```rust
pub struct Article {
pub id: u64,
pub body: String,
pub title: String,
pub author: User,
pub comments: Vec
resource!(Article, |&self| { // Define the id with an expression that returns a string. id self.id.to_string();
// Define the resource "type"
kind "articles";
// Define attributes with a comma seperated list of field names.
attrs body, title;
// Define a virtual attribute with a block expression
attr "preview", {
self.body
.iter()
.cloned()
.take(140)
.collect::<String>()
}
// Define a relationship with granular detail
has_one "author", {
// Data for has one should be Option<&T> where T: Resource
data Some(&self.author);
// Define relationship links
link "self", format!("/articles/{}/relationships/author", self.id);
link "related", format!("/articles/{}/author", self.id);
// Define arbitrary meta members with a block expression
meta "read-only", true
}
// Define a relationship with granular detail
has_many "comments", {
// Data for has one should be an Iterator<Item = &T> where T: Resource
data self.comments.iter();
// Define relationship links
link "self", format!("/articles/{}/relationships/comments", self.id);
link "related", format!("/articles/{}/comments", self.id);
// Define arbitrary meta members with a block expression
meta "total", {
self.comments.len()
}
}
// You can also define links with granular details as well
link "self", {
href format!("/articles/{}", self.id);
}
// Define arbitrary meta members with a block expression
meta "copyright", {
format!("© 2017 {}", self.author.full_name())
}
}); ```
The json-api-rocket crate provides responders as well as a fairing for catching errors and returning JSON API error documents.
```rust
extern crate jsonapi; extern crate jsonapi_rocket; extern crate rocket;
mod models;
use jsonapirocket::JsonApiFairing; use jsonapirocket::response::{Collection, Member};
use models::Article;
fn collection() -> Collection
fn member(id: u64) -> Member
fn main() { rocket::ignite() .attach(JsonApiFairing) .mount("/articles", routes![collection, member]) .launch(); }
```
Licensed under either of
at your option.
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.