Introduction: Why do I need a RESTful service on Meteor
Meteor is attracted by its ease of use and the ability to very quickly create a working application with a minimal set of functions. Meteor has a well developed community. There are many useful add-on modules that do not require complex configuration, and can be used immediately after installation. There is good documentation, examples and a large number of posts on forums like
StackOverflow . Meteor is a full-stack framework that offers convenient and multifunctional server integration with a client. So why go beyond this interaction and create a
RESTful service?
A client-server application , in essence, consists of 2 independent parts that interact through a specific interface. In addition, each part of the client-server application can be created by different people or teams. The developers of the client part are not at all limited to using Meteor, they can use any other JS framework, the client doesn’t even have to be written in JS, for example, an Android application written in Java, or iOS written in Objective C.
These are the reasons that made me choose Meteor to build a back end in my project, and look for ways to create a RESTful service on Meteor.
Overview of available modules
After some time spent searching for suitable modules, I got the following list:
')
github.com/meteorhacks/picker - uses routing similar to that used in, say,
Express.jsPicker.route('/post/:_id', function(params, req, res, next) { var post = Posts.findOne(params._id); res.end(post.content); });
with the ability to send a response in JSON format
github.com/crazytoad/meteor-collectionapi allows you to create API Endpoints for CRUD operations on collections. There are no mechanisms for differentiating access levels (for example: guest, authorized user, administrator), authorization, or creating custom endpoints.
github.com/kahmali/meteor-restivus allows you to create API Endpoints for CRUD operations on collections. There are mechanisms for authorization, delimitation of access levels and the creation of custom endpoints. This package will be described in more detail below.
github.com/Differential/reststop2 is a stale and unsupported solution. On the main page of the resource there is a link to the Restivus project with the indication that all the existing functions of this solution are also in Restivus.
github.com/stubailo/meteor-rest allows you to create API Endpoints for CRUD operations on collections. There are mechanisms to authorize and create custom endpoints. There are no mechanisms for differentiating access levels. Documentation lacks clarity and working examples. Allows you to integrate Restivus to create custom endpoints.
Since Restivus has all the features I need, and was marked by the greatest number of stars on both GitHub and
Atmosphere , as well as due to the fact that 2 other projects from the list referred to Restivus, I decided to opt for it.
Using Collections, CRUD Operations, and Access Levels
Using Restivus is very simple. To install, type in the console:
meteor add nimble:restivus
To create a RESTful service, add the following terms to the server code:
if (Meteor.isServer) { var Api = new Restivus({useDefaultAuth: true}); }
API arguments are passed in the arguments of the constructor. The value of the `useDefaultAuth` option is discussed in the following section.
If you have a registered collection, say
var Contacts = new Mongo.Collection('contacts');
And you want to access it through CRUD operations through the API, in the simplest form it is enough to do:
Api.addCollection(Contacts);
This will create the following Endpoints:
`getAll` Endpoint
GET / api / collection
Return information about all elements of the collection
`post` Endpoint
POST / api / collection
Add a new item to the collection
`get` Endpoint
GET / api / collection /: id
Return information about a collection item
`put` Endpoint
PUT / api / collection /: id
Edit collection item
`delete` Endpoint
DELETE / api / collection /: id
Remove item from collection
The response format is always the following:
{status: "success", data: {}}
The `api /` prefix can be replaced by another by setting the `apiPath` option passed during the creation of the API. As you can see, each API operation on the collection has its own identifier. It can be used as follows:
Api.addCollection(Contacts, { excludedEndpoints: ['getAll', 'put'], routeOptions: { authRequired: true }, endpoints: { get: { authRequired: false }, delete: { roleRequired: 'admin' } } });
In this case, the collection was registered in the API with the operations delete, get, and post. For the get operation, authorization is not required; for the post and delete operations, it is required; only the administrator can perform the delete operation. Read more about authorization and authentication.
Authorization and Authentication
After registering in the users collection API, 2 special endpoints are added:
POST / api / login
GET | POST / api / logout
Despite the assurances from the documentation, in the version of Restivus, which I used (0.8.4), deblocking worked only with a GET request. More about this can be found
here .
To log in, you need to pass the username and password in the following form:
curl http://localhost:3000/api/login/ -d "username=test&password=password"
In case of failure in the body of the answer will come the string 'Unauthorized'.
If successful, the following answer will come:
{status: "success", data: {authToken: "f2KpRW7KeN9aPmjSZ", userId: fbdpsNf4oHiX79vMJ}}
Save the token and user id in order to transmit in the headers requests to the API Endpoints requiring authorization:
curl -H "X-Auth-Token: f2KpRW7KeN9aPmjSZ" -H "X-User-Id: fbdpsNf4oHiX79vMJ" http://localhost:3000/api/contacts/
Custom endpoints
Api.addRoute('contacts/favorite/:userId', { get: { authRequired: false, roleRequired: ['author', 'admin'], action: function () { this.response.write({"user-id": this.urlParams.userId}); this.done(); } } });
This code snippet registers the Endpoint API at api / contacts / favorite /. The `userId` parameter passed as part of the path will be available as` this.urlParams.userId`. GET request parameters will be available via `queryParams`. If you do not need to describe options for authorization and access levels, then you can use the short form:
Api.addRoute('contacts/favorite/:userId', { get: function () { this.response.write({"user-id": this.urlParams.userId}); this.done(); } });
Results: Pros and cons of building a RESTful service on Meteor
As we can see, Meteor once again provided a convenient tool for rapid prototyping, which is very valuable in the early stages of the project. Often applications do not go beyond working with text and numeric data. Thus, we have: Meter and Restivus + resource mechanism (available, for example, in Angular or Vue) = interaction between the client and server, created in minutes.