Elodo
Communicate with any REST API in an elegant and object oriented way.
TOC
Quick preview
const post = Post; // POST request to "http://api.com/api/posts"await post;
posttitle = 'What is Elodo? Amazing!'; // PUT request to "http://api.com/api/posts/1"await post;
// GET request to "http://api.com/api/posts?include=comments,author"const posts = await Post ; // Each post is tranformed to an instance of Postconst post = posts0;await post;
Installation
npm install elodo
npm install axios
Setup
Structure
/src
├── /api
| ├── /resources
| | ├── post.js
| | └── comment.js
| └── client.js
| └── resource.js
| └── router.js
├── ...
└── app.js
Resource
api/resource.js
;;; const Resource = ;
api/router.js
; const router = ; routerprefix'http://api.com/api/v1/' { // Register each crud action routerindex'posts' `posts`; router; router; router; router; // Or register all crud actions at once // $index GET /posts // $store POST /posts // $show GET /posts/{post.id} // $store POST /posts/{post.id} // $update PUT /posts/{post.id} // $destroy DELETE /posts/{post.id} router;};
api/client.js
; const client = { return Axios;};
api/resources/post.js
; { return id: null title: null body: null ; } { return 'posts'; // Used to create the route path }
Now you can use the post resource in app.js
or any other file
; const posts = await Post; // GET request to "/posts" const post = await Post; // GET request to "/posts/1" await post; // GET request to "/posts/1" await post; // POST request to "/posts" await post; // PUT request to "/posts/1" await post; // DELETE request to "/posts/1"
Fetching resources
Fetch filtered list of resources
Fetch list of resources sorted by an attribute
Fetch list of resources with relationships
Fetch list of resources with selected fields
Fetch list of resources with appended fields
Fetch list of resources with specific params
Fetch paginated list of resources
Fetch list of resources
// GET /postsconst posts = await Post;
Fetch single resource
Find a resource by primary id
// GET /posts/1const post = await Post;
Show a resource by its attributes
// GET /posts/1const post = Post;await post;
You can also use the $refresh
alias
// GET /posts/1const post = Post;await post;
Fetch filtered list of resources
// GET /posts?filter[title]=Helloconst posts = await Post ;
You can also use the where
alias
// GET /posts?filter[title]=Helloconst posts = await Post ;
Fetch list of resources sorted by an attribute
// GET /posts?sort=titleconst posts = await Post ;
Sort descending
// GET /posts?sort=-titleconst posts = await Post ;
Combine multiple sorts
// GET /posts?sort=id,-nameconst posts = await Post ;
Fetch list of resources with relationships
// GET /posts?include=comments,authorconst posts = await Post ;
Fetch list of resources with selected fields
// GET /posts?fields[posts]=id,titleconst posts = await Post ;
Fetch list of resources with appended fields
// GET /posts?append=published_atconst posts = await Post ;
Fetch list of resources with limited resultes
// GET /posts?limit=15const posts = await Post ;
Fetch list of resources with specific params
// GET /posts?param=valueconst posts = await Post ;
Fetch paginated list of resources
// GET /posts?page[size]=15&page[number]=1const pagination = await Post ; // Pagination data is tranformed to instances of Postconst post = paginationdata0;await post;
Set the page directly
// GET /posts?page=1await Post ;
Use with the limit param
// GET /posts?page=1&limit=15await Post ;
Persisting resources
Store resource
// POST /postsconst post = Post;await post;
Or use the $save
alias
// POST /postsconst post = Post;await post;
Update resource
// Put /posts/1const post = await Post;posttitle = 'Updated title';await post;
Delete resource
// DELETE /posts/1const post = await Post;await post;
Or use the $delete
alias
// DELETE /posts/1const post = await Post;await post;
Relationships
Start with defining your relationship routes
; const router = ; routerprefix'http://api.com/api/v1/' { // $index GET /posts // $store POST /posts // $show GET /posts/{post.id} // $store POST /posts/{post.id} // $update PUT /posts/{post.id} // $destroy DELETE /posts/{post.id} router; // $index GET /posts/{post.id}/comments // $store POST /posts/{post.id}/comments // $show GET /posts/{post.id}/comments/{comment.id} // $store POST /posts/{post.id}/comments/{comment.id} // $update PUT /posts/{post.id}/comments/{comment.id} // $destroy DELETE /posts/{post.id}/comments/{comment.id} router;};
const post = Post;const comment = Comment; // POST /posts/1/commentsawait comment; // POST /commentsawait comment;
Cancel requests
;; const source = ; Post ; source;
Cancel any crud action
;; const source = ;const post = Post; post ; source;
Cast attributes
The cast property allows you to convert attributes coming from the server.
Build in cast types are: number
, float
, int
, bigint
, boolean
, string
, date
, json
, and json.parse
.
; { return id: null title: null published_at: null ; } { return id: 'int' published_at: 'date' ; } { return 'posts'; }
Cast nested properties
; { return object: prop: null ; } { return 'object.prop': 'boolean' ; } { return 'posts'; }
Custom cast
Add a function to that returns the transformed value.
; { return id: null title: null published_at: null ; } { return value ; } { return 'posts'; }
Cast to relationship
;; { return id: null title: null comments: null ; } { return Comment ; } { return 'posts'; }
File uploads
Change the content type of the resource to formdata
./api/resources/post.js
; { return id: null thumbnail: null ; } { return 'formdata'; } { return 'posts'; }
In ./app.js
or any other file
; const fileInput = document;const file = fileInputfiles0; const post = Post; // POST request to "/posts" with file in formdataawait post;
Options
To add or override options you can create a base resource
;;; const BaseResource = ; /** * Default attributes */ { return id: null ; } /** * Default route */ { return 'default.route'; } /** * Default primary key */ { return 'id'; } /** * Default casts */ { return {}; } /** * Default content type */ { return 'json'; } /** * Custom $latest function */ static return this ;