# API Design You want to help out? Awesome! Chances are you don't know how everything is structured, where everything is, etc. This document will help you out by explaining how the API works, how it's structured, the macros used to generate all of the code work and how to add new endpoints. ## Builder Pattern Queries One of the main things to understand about this API is that each query is following the builder pattern. Function calls build up a query that can eventually be executed. Using a type that implements `Client`, it can then be used to build up a query through chained function calls. Think of the first function call as the type of operation (GET, POST, PUT, PATCH and DELETE) and every other function call as building up the url, taking parameters as needed. This is the builder pattern that's implemented elsewhere in Rust, usually when using Rust in a more functional style. Now what's important to note is that at each function call we get a different type. This type limits what functions can be called so that users can only make valid requests. You can only build up the url until you have no choice but to execute the request to the API. This means that the library is implementing a [Directed Acyclic Graph](https://en.wikipedia.org/wiki/Directed_acyclic_graph) (DAG) under the hood! ## Macros Macros are used to generate most of the code needed for any Web API. Here are the macros you need to understand, how to use them, and what they do: - `new_type!` is used to declare a new type that represents a step in building up the Url. Here's how it's used: ```rust new_type!( User // <-- This means we've declared a new struct called User UserRepo // <-- This means we've declared a new struct called UserRepo ); ``` This expands out to: ```rust pub struct User<'a> { pub(crate) request: Result>, pub(crate) core: &'a mut Core, pub(crate) client: &'g Rc>, pub(crate) parameter: Option, } pub struct UserRepo<'a> { pub(crate) request: Result>, pub(crate) core: &'a mut Core, pub(crate) client: &'g Rc>, pub(crate) parameter: Option, } ``` It contains a value request which is the current value of the request and core which contains a mutable reference to a Tokio Core type which is used to run the request when it's ready. It also contains an optional parameter which can be used to specify GET/POST parameters. Note you'll need to use 'a as a lifetime for any `impl` of the new type you need to implement manually. - `from!` is used to create an implementation of `From` of a type you specify to another type. It's needed every time you want one type to turn into another. This is needed for the `func!` macro. If you forget to do this it will not work. It can be used in three different ways: ```rust from!( @TypeA //<-- Create a From implementation from A to B ?> TypeB = "param" // which includes a GET/POST parameter ); // named 'param' from!( @TypeA //<-- Create a From implementation from A to B => TypeB ); from!( @TypeA //<-- Create a From implementation from A to B -> TypeB = "path" // which appends a path to the constructed ); // URL ``` - `impl_macro!` is used to create functions on types created by the `new_type!` macro. This is used to implement the functions used when contructing a request. It can be used in four different ways: ```rust impl_macro!( //<-- Create a function 'func' which, when @TypeA // called, returns a B |=> func -> TypeB ); impl_macro!( //<-- Create a function 'func' which, when @TypeA // called, returns a B with 'path' added |=> func -> TypeB = path // to the request URL. 'path' is the name ); // of the variable is for documentation impl_macro!( //<-- Create a function 'func' which, when @TypeA // called, returns a B with a GET/POST |?> func -> TypeB = param // parameter. 'param' is the name of the ); // variable and is for documentation ``` - `exec!` is used to terminate the request chain. The result is an implementation of the Executor trait on the type. This allows the execute method to be called in order to actually perform the request. ```rust exec!( TypeA // <-- Creates an impl of Executor for Type A. TypeB // <-- Creates an impl of Executor for Type A. ); // This is neccessary for every type which needs an execute method. ```