macro_rules! resource {
($target:ident, |&$this:ident| { $($rest:tt)* }) => { ... };
}
Expand description
A DSL for implementing the Resource
trait.
§Examples
The resource!
macro is both concise and flexible. Many of the keywords are
overloaded to provide a higher level of customization when necessary.
Here is a simple example that simply defines the resources id, kind, attributes, and relationships.
#[macro_use]
extern crate json_api;
struct Post {
id: u64,
body: String,
title: String,
author: Option<User>,
comments: Vec<Comment>,
}
resource!(Post, |&self| {
// Define the id.
id self.id;
// Define the resource "type"
kind "posts";
// 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;
});
Now let’s take a look at how we can use the same DSL to get a higher level customization.
#[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;
// Define a virtual attribute with an expression
attr "preview", {
self.body
.chars()
.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 self.author.as_ref();
// 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 an expression
meta "copyright", self.author.as_ref().map(|user| {
format!("© 2017 {}", user.full_name())
});
});