Resources & Resource Controllers
In the lesson about creating a service, we created a service to manage the rentals. We then updated the
rental.get
method in the rental controller to return the list of rentals managed by the rental service. There were other methods in the rental service, such as create()
, get(id)
, and remove(id)
, that we did not use. So, let's update our application to provide routes that call use these methods.A resource controller is a specialized controller that supports CRUD operations (i.e., create, retrieve, update, and delete). Blueprint provides a base implementation of a resource controller, which you can extend in your application as needed. Since we have a service that supports CRUD operations, let's update the
rental
controller become a resource controller.First, update the rental controller by changing
Controller
to ResourceController
, and define the name property on the controller as rental
.app/controllers/rental.js
const {
ResourceController,
Action,
service
} = require ('@onehilltech/blueprint');
/**
* @class rental
*/
module.exports = ResourceController.extend ({
name: 'rental',
rentals: service (),
get () {
return Action.extend ({
execute (req, res) {
const data = this.controller.rentals.rentals;
res.status (200).json ({ data });
}
})
}
});
What we did was extended the
ResourceController
instead of the Controller
. This gives our controller the ability to selectively extend the actions defined in the ResourceController
class. The get()
method is one of the methods defined on the ResourceController
, so we do not have do anything.The
ResourceController
extends the Controller
, which is why theResourceController
is still considered a Controller.We also defined the
name
property. This is a required property because the router uses this name when it is auto-generating the routes for the corresponding resource, as shown in the table below with their corresponding method on the ResourceController
.Method | Verb | Path | Description |
create() | POST | / | Create a new resource |
getAll() | GET | / | Query the resources |
getOne() | GET | /:nameId | Get a single resource |
update() | PUT | /:nameId | Update an existing resource |
delete() | DELETE | /:nameId | Delete an existing resource |
When implementing the actions on of a resource controller, you only need to override methods that correspond to operations that you want to support. In our super-rental API server, we only want to support the following CRUD operations:
create
getOne
getAll
delete
The
ResourceController
methods that are not overridden return a 404 Not Found
HTTP response to the client.Let's first implement the
getOne()
and getAll()
. The getOne() method is define an action that returns a single resource and the getAll() method is define an action that returns resources that match the query. If there is no query, then we should return all the resources. Below is the implementation of getOne()
and getAll()
.app/controllers/rental.js
const {
ResourceController,
Action,
service
} = require ('@onehilltech/blueprint');
/**
* @class rental
*/
module.exports = ResourceController.extend ({
name: 'rental',
rentals: service (),
// query all the resources
getAll () {
return Action.extend ({
execute (req, res) {
const data = this.controller.rentals.rentals;
res.status (200).json ({ data });
}
})
},
// get a single resources, or return 404 Not Found.
getOne () {
return Action.extend ({
execute (req, res) {
const { rentalId } = req.params;
const rental = this.controller.rentals.get (rentalId);
if (rental) {
res.status (200).json ({ data: [rental] });
}
else {
res.sendStatus (404);
}
}
})
}
});