Evolution of a Node.js API, Zoe.js — Request & Response
An API
receives requests and gives back responses. This chapter is about Request Encapsulation and Response Transformation.
Request
When I’m working on a code I like to show my intentions explicitly and that’s why Zoe.js
has Request objects
for creating or updating resources.
Request object
A Request object
has 2 goals:
- it shows the entire Request data what is possible
- it validates the entire Request data
Number 1 helps you with understanding and reading the code. With achieving Number 2 you’ll end up a Request object
which you can use anywhere in your code, knowing it contains valid data.
For validation requests we’re going to use joi data validator. joi
has a simple still powerful schema description language for validating data. Now install joi
with:
npm install joi
In order to accomplish a proper validation with joi
we need 2 helper classes:
- Validation Error class
- Request validator service class
Validation Error class
When a validation error occurs we can throw this Error class. We’ll use this to build the HTTP
Response, json body will contain name
and metadata
, HTTP
status code will be 422
.
Request validator service class
Request validator will reduce code duplication as a general service class in our project. It simply validates this._request
data based on this._schema
and if an error occurs it throws ValidationError
.
Product create request
Now we have everything to create our first Request class which is the ProductCreateRequest
.
What we see here is that ProductCreateRequest
extends our RequestValidator
. this._schema
contains joi
's schema, there's a required minimum 5 chars long string id
property, a required minimum 3 chars long name
property, and a required positive integer price
property. Finally we check the errors and we have getter methods for all the request properties and a buildProductData
method which builds a product data object.
In order to be able to fetch the HTTP
Response JSON
body in the Controller Layer we have to add an Express.js
middleware to the app/config/app.js
file which parses the incoming JSON
request and puts it in to the req.body
property.
app.use(express.json())
When it’s done we can use our ProductCreateRequest
class in the Controller layer.
Additionally I put the logic inside a try...catch
block to catch all the exceptions, currently a validation error can occur.
Validation works because there are no id
and price
properties in the request.
I just complete the product create request body with id
and price
and now it works like a charm!
(You can check the ProductUpdateRequest
class in the source code).
Response
We’re done with the Request part, now we’d like to give back a Response. For giving back a Response we’re going to use Resource
classes to be able to Transform the Response as we'd like. Think of a password field what you don't want to expose, or a secret field which needs to be exposed by a specific admin role. Resource
class helps you with that.
There is nothing special here, just a plain JS class which stores data. As you can see currently I don’t have any special logic. Let’s use it in our Controller for giving back a Response.
That’s it, now the response has its own body with the product data.
Another option is to add a Location
header with the new Resource URL, in that case you don't need a body here.
Source Code
Next chapter
Soon
Chapters
Adams Academy
theadamsacademy@gmail.com