Simplified CRUD with itsa-react-server

CRUD, create, read, update, and delete, are the four basic functions of persistent storage. Itsa-react-server makes these functionalities extremely easy. In case you missed the article about itsa-react-server: see here.

Personally, I love the way itsa-react-server has set up CRUD. Because of its simplicity, it makes your web applications really manageable.

Routing

Before going deeper into each CRUD process, I will define a router definition to handle all routes. As my previous article described: itsa-react-router uses routes conform Hapi.js.

When working with CRUD, you should use authenticated routes, which ensures that only authenticated visitors manipulate your database. In a next article, I will explain how easy it is to implement authentication with its-react-server, but for now I will just show the two types of route-files: with and without authentication.

Routing without authentication (bad example):

Routing with authentication (good example):

Obviously, you should use the latter.

Notice the difference between the POST and PUT request. As a POST assumes to receive all the properties, a PUT request may have only parts (the fields that needs to be updated and a key).

Also notice that I have created 2 different routes for getting a user. The difference is explained below (CRUD: Reading data).

To create CRUD functionality, we need both client side code, as well as server side code to process the data.

The client side code is typically set up in a page, which is a React.js Component. Itsa-react-server uses Views for this and also has an app file (/src/app.js) with a special io method. App.io gives you Promised ajax features, like window.fetch. However, app.io is more powerful: it works on all browsers, has an abort-method and dedicated CRUD methods.

The server side code needs to be an action file in case we call reply.action(), or a view file in case we call reply.reactview(). Both files should equal their names with the argument passed through. Actions files all reside in the /src/actions folder, views inside /src/views. In case of the views, a matching model can be defined: models have the same name (but with a .js extention) and reside in the /src/models folder.

CRUD: Creating data

The route for creating data will be followed by the url /actions/insertuser, which should be a POST request. To create this functionality, we need both client side code, as well as server side code to process the data.

Client side page for creating user:

file: /views/new-user.jsx:

Note: On some places I replaced this by instance. This is not because of scoping (arrow functions keep the scope), but for optimizing UglifyJS, which cannot minify this.

Server side code for creating user:

file: /actions/insertuser.js

Note: POST requests expose their fields on request.payload

This seems a lot of code, but actually is very clean and easy to manage.

CRUD: Reading data

There are 2 different ways of reading data, depending on your use case.

First case is “just getting data” through an ajax request. F.e. when building a SaaS. You typically do not use this kind of reading data when you want to render it into a view: it would break RESTful application and server side rendering.

Second case is when using the model-data to be rendered in a view, as this.props. This is the most likely scenario. It leads to RESTful and server side rendered pages.

The route has defined different routes for both purposes:

Case 1: getting data through an ajax request

Client side page for reading user-data:

file: /views/show-userdata.jsx:

Server side code for reading user-data:

file: /actions/getuser.js

Note: GET requests expose their arguments on request.query

Case 2: getting model-data to be rendered in a view

Client side page for reading user:

file: /views/user-details.jsx:

Server model:

file: /models/user-details.js

Note: Route params (defined with curly brackets in the route) expose their parameters on request.params

CRUD: Updating data

Client side page for reading user:

file: /views/edit-user.jsx:

Server model:

file: /models/edit-user.js

Server side code for updating user:

file: /actions/updateuser.js

Note: PUT requests expose their fields on request.payload

CRUD: Deleting data

Client side page for deleting user:

file: /views/delete-user.jsx:

Server model:

file: /models/delete-user.js

Server side code for deleting user:

file: /actions/deleteuser.js

Note: DELETE requests expose their arguments on request.query

In a next article, I will tell more about authentication with itsa-react-server.