Adonis Provider/Middleware package to create RESTful API for Lucid ORM.
- Install required packages
adonis install @adonisjs/fold --yarn
yarn add lucid-restful
or
adonis install @adonisjs/fold
npm install lucid-restful
- Edit
/start/app.js
const providers = [
...
'lucid-restful/providers/LucidRestfulProvider'
]
- Edit
/start/routes.js
Route.restful('/restapi')
The middleware is schema-agnostic, allowing any json document to be persisted and retrieved from database.
Route | Method | Notes |
---|---|---|
/:collection | GET | Search the collection (Filters: under development) |
/:collection | POST | Create a single document |
/:collection | PUT | Method Not Allowed |
/:collection | DELETE | Method Not Allowed |
/:collection/:id | GET | Retrieve a single document |
/:collection/:id | POST | Method Not Allowed |
/:collection/:id | PUT | Update a document |
/:collection/:id | DELETE | Remove a single document |
/:collection/count | GET | Count the collection |
/:collection | PATCH | Method Not Allowed |
/:collection/:id | PATCH | Undeveloped Method |
Get examples | Notes |
---|---|
/post | List all posts |
/post/1 | Retrieve post with id 1 |
/post?id>10&id<100 | List posts id between 11 and 100 |
/posts?with=comments | List posts with comments |
/posts?with=comments(post_id,body) | List posts with comments and selected columns |
/posts/1?with=comments | Retrieve post 1 with comments |
/posts?order=-title | List posts sorted by title desc |
/posts?page=2&limit=100 | List from 101 to 200 |
/post?!title | List posts if title IS NULL |
/post?title | List posts if title IS NOT NULL |
The query API (GET /:collection) uses a robust query syntax that interprets comparision operators (=, !=, >, <, >=, <=) in the query portion of the URL using.
For example, the URL https://localhost/restapi/users?name=John&age>=21
would search the User collection for any entries that have a name of "John" and an age greater than or equal to 21.
[
{ id: '1', name: 'John', age: 21 }
]
Paginate
URL https://localhost/restapi/users?page=1&limit=10
Ascending
URL https://localhost/restapi/users?order=name&page=1&limit=10
Descending
URL https://localhost/restapi/users?order=-name
Use the q
parameter to perform a substring search specified in the 'qSearchFields' attribute of the model.
URL https://localhost/restapi/users?q=John%
[
{ id: '1', name: 'John', age: 21 }
{ id: '1', name: 'Edward', lastName: 'Johnathan', age: 21 }
]
class User extends Model {
...
}
User.qSearchFields = ['name', 'lastName']
Documents are saved using the Lucid ORM save function. An example post return the document saved:
URL: https://localhost/restapi/users
Data: { name: 'Peter', age: 19 }
Result:
{
id: 2,
name: 'Peter',
age: 19
}
Documents are saved using the Lucid ORM save function.
URL: https://localhost/restapi/users/2
Data: { age: 17 }
Result:
{
id: 2,
name: 'Peter',
age: 17
}
URL: https://localhost/restapi/users/count?age>=18
Result
{ count: 2 }
This midlaware add before paginete suporte in all restful calls.
class Post extends Model {
static boot () {
super.boot()
this.addHook('beforePaginate', async (query, request) => {
let params = request.get()
if (params.customfilter) {
query.where(..., ...)
delete params.customfilter
}
})
}
...
}
To get a relation to another model using "with", just use the "with" parameter as an examples:
URL: https://localhost/restapi/comment?with=post
Result:
[{
id: 1,
body: 'Lorem ipsum',
post_id: 1,
post: {
id: 1,
title: 'Lipsum',
body: 'It`s awesome',
...
}
}]
URL: https://localhost/restapi/post?with=comments
Result:
[{
id: 1,
title: 'Lipsum',
body: 'It`s awesome',
comments: [{
id: 1,
body: 'Lorem ipsum',
post_id: 1,
...
}]
}]
if you need to select some columns in the related table. Just indicate the columns in parentheses as below:
URL: https://localhost/restapi/post?with=comments(post_id,body)
Result:
[{
id: 1,
title: 'Lipsum',
body: 'It`s awesome',
comments: [{
post_id: 1,
body: 'Lorem ipsum',
}]
}]
Note: It is necessary to inform the join columns.
The fillable property specifies which attributes should be mass-assignable. This can be set at the model class.
class Post extends Model {
...
}
Post.fillable = ['title', 'body']
class Post extends Model {
...
comments () {
return this.hasMany('App/Models/Comment')
}
}
Post.cascadeFillable = ['comments']
URL: https://localhost/restapi/post
Data: { title: 'Lipsum', comments: [{ body: 'Lorem ipsum' }] }
Result:
[{
id: 2,
title: 'Lipsum',
comments: [{
id: 3,
body: 'Lorem ipsum',
post_id: 2,
}]
}]
To validate the requisitions, add in the app/Validators/
folder the validators with the same name as the templates.
Requires @adonisjs/validator to enable.
app/Models/Post.js
app/Validators/Post.js
class Post extends Model {
...
commentsCount () {
return this.belongsTo('App/Models/Comment')
.groupBy('post_id')
.select('post_id')
.select(Database.raw('count(id)'))
}
}
URL: https://localhost/restapi/post?with=commentsCount
Result:
[{
id: 2, title: 'Lipsum',
commentsCount: { post_id: 2, count: 1 }
},{
id: 3, title: 'Lorem',
commentsCount: { post_id: 3, count: 13 }
}]
Route | Type | Default | Notes |
---|---|---|---|
modelfolder | String | App/Models | Change Models Folder |
if you need to customize the data output.
Route.resource('/restapi/:collection/:id*', '_Custom_Controller_').middleware(['lucid-restful'])