Creating RESTful Services on Meteor
- From the sandbox
- Tutorial
Introduction: Why you need a RESTful service on Meteor
Meteor attracts with its ease of use and the ability to very quickly create a working application with a minimum 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 forum posts like StackOverflow . Meteor is a full-stack framework that offers convenient and multifunctional server integration with the client. So why go beyond this interaction and create a RESTful service?
Client server application, in fact, consists of 2 independent parts that interact through a specific interface. Moreover, 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 does not even have to be written in JS, it can be, for example, an Android application written in Java, or iOS written in Objective C.
These are the reasons made me choose Meteor to build the 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, say, in Express.js
Picker.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 Endpoints API for CRUD operations on collections. There are no mechanisms for delimiting access levels (for example: guest, authorized user, administrator), authorization, or creating custom endpoints.
github.com/kahmali/meteor-restivus allows you to create Endpoints APIs for CRUD collection operations. There are mechanisms for authorization, delimiting access levels and creating custom endpoints. This package will be described in more detail below.
github.com/Differential/reststop2 is an outdated and unsupported solution. On the main page of the resource - a link to the Restivus project indicating that all the available functions of this solution are also in Restivus.
github.com/stubailo/meteor-rest allows you to create Endpoints APIs for CRUD collection operations. There are authorization and custom endpoints creation mechanisms. There are no mechanisms for delimiting access levels. The 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 largest number of stars on both GitHub and Atmosphere , as well as due to the fact that 2 other projects from the above list referred to Restivus, I decided to choose it on 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 dates to the server code:
if (Meteor.isServer) {
var Api = new Restivus({useDefaultAuth: true});
}
The constructor arguments pass API options. The value of the `useDefaultAuth` option is discussed in the following section.
If you have a collection registered, say
var Contacts = new Mongo.Collection('contacts');
And you want to open access to it through CRUD operations through the API, in the simplest form it’s enough to do:
Api.addCollection(Contacts);
This will create the following Endpoints:
`getAll` Endpoint
GET / api / collection
Return information about all elements of the
post` collection Endpoint
POST / api / collection
Add a new element to the collection`
get` Endpoint
GET / api / collection /: id
Return information about the element the
`put` collection Endpoint
PUT / api / collection /: id
Change
the` delete` collection element Endpoint
DELETE / api / collection /: id
Delete the item from the collection
The response format is always as follows:
{status: "success", data: {}}
The prefix `api /` can be replaced with another by setting the `apiPath` option, passed during the creation of the API. As you can see, each collection operation API 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, a collection with delete, get, and post operations was registered in the API. For the get operation, authorization is not required, for post and delete operations, it is required, while only the administrator can perform the delete operation. About authorization and authentication, read on
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 that I used (0.8.4), logging only worked with a GET request. You can see more about this here .
To log in, you need to transfer the username and password in the following form:
curl http://localhost:3000/api/login/ -d "username=test&password=password"
In case of failure, the string 'Unauthorized' will come in the response body.
If successful, the following answer will come:
{status: "success", data: {authToken: "f2KpRW7KeN9aPmjSZ", userId: fbdpsNf4oHiX79vMJ}}
Save the token and user id in order to send authorization requests to the Endpoints API requests:
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 piece of code 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 through `queryParams`. If you do not need to describe the options for authorization and access levels, then you can use a short form:
Api.addRoute('contacts/favorite/:userId', {
get: function () {
this.response.write({"user-id": this.urlParams.userId});
this.done();
}
});
Results: The pros and cons of building a RESTful service on Meteor
As we can see, Meteor once again provided a convenient tool for quickly creating a prototype, which is very valuable in the early stages of the project. Often applications do not go beyond working with textual and numerical data. Thus, we have: Meter and Restivus + resource mechanism (available, for example, in Angular or Vue) = interaction between the client and server created in a matter of minutes.