How would you go about creating a restful web service using Meteor. I would like to create apps in Appcelerator that hook into the same backend.
Can Meteor solve this problem?
How would you go about creating a restful web service using Meteor. I would like to create apps in Appcelerator that hook into the same backend.
Can Meteor solve this problem?
I suppose you probably could create a RESTful service using Meteor, but it's not really what the framework is intended for -- one of the main benefits of Meteor is tight interaction between the client and the server, and a web service doesn't have a client side. I'd recommend looking into either writing a web service back end in node.js on its own or something like https://github.com/intridea/grape if you like Ruby.
I did a full write-on on this in Meteorpedia:
http://www.meteorpedia.com/read/REST_API
The post reviews all 6 options for creating REST interfaces, from highest level (e.g. smart packages that handle everything for you) to lowest level (e.g. writing your own connectHandler).
Additionally the post covers when using a REST interface is the right or wrong thing to do in Meteor, references Meteor REST testing tools, and explains common pitfalls like CORS security issues.
I originally answered this question here, but to recap:
For adding RESTful methods on top of your data, look into the Collection API written for Meteor:
https://github.com/crazytoad/meteor-collectionapi
As for authentication for accessing the database, take a look at this project:
https://github.com/meteor/meteor/wiki/Getting-started-with-Auth
Both are definitely infantile in development, but you can create a RESTful API and integrate it with a mobile native client pretty easily.
I know this is an old thread, but in case anyone stumbles across it, I published a package for writing REST APIs in Meteor 0.9.0+:
https://github.com/kahmali/meteor-restivus
It was inspired by RestStop2 and built with Iron Router's server-side routing. In my not-so-humble opinion, it's a better solution than anything posted here thus far.
UPDATE: To clarify why I think it's a "better" solution than those mentioned, I'll just point out the differences between each:
CollectionAPI:
CollectionAPI is limited to exposing very basic CRUD operations on your collections. For my use, which is consuming the REST API in mobile apps, it can be extremely wasteful to send down entire documents, and most of the time I need to do some additional processing of data (for instance, sending a Google Cloud Message in a REST endpoint for adding a friend, but only if the friend is successfully added). CollectionAPI gives you a hook that runs before the endpoint is executed, but from what I understand there is nothing immediately before the response, so you have no way of modifying the data that is returned. For authentication, CollectionAPI allows you to define an authToken that must be passed with each request. This acts more like a traditional api key, as it appears to be hard-coded into your app, and would therefore be the same for every user.
Restivus, since it is not limited to automated work on collections, gives you complete control over your endpoints. It now provides all the functionality included in Collection API. It supports user authentication and role permissions as well, so you can identify the user making the request (and easily access that user from within authenticated endpoints). It provides a login and logout endpoint as well to assist with that. I will provide a code example for Restivus at the end.
HTTP.publish:
From what I understand, this is similar to CollectionAPI in that it is limited to exposing basic CRUD operations on collections. This one is more specifically tied to Meteor's publishing, and allows you use a publish function for handling GET requests. I'm confused by the documentation, but it may or may not have some basic authentication available. I haven't used this before, but I'm not a big fan of the API for it, which feels a bit clunky. Once I'm publishing more extensively I'll try to revisit it. The same team has another package called HTTP.methods which doesn't give you the access to the publish functions, but has a similar api to Restivus and, at the time, similar functionality.
Restivus is "better" because it doesn't limit you to using your publish functions, and therefore allows for a much finer-grained control over your endpoints. If you are just looking to expose your publish functions to an external API, I would recommend you stick with HTTP.publish. Restivus also has a simpler API and supports the HTTP PATCH method (which no other package seems to acknowledge exists). Their HTTP.methods package is pretty similar to Restivus, except it lacks PATCH support, and although it offers some basic authentication, I believe you only have the ability to make all endpoints authenticated, or none. Restivus will allow you to control that on a per-endpoint (not just per-route) level. Role permissions (e.g., user, admin) on endpoints are also available on Restivus, but I don't see anything about that for HTTP.methods.
Meteor Router:
This has been deprecated in favor of Iron Router, please see below.
Iron Router:
Iron Router is awesome, but it is not specifically designed for building REST APIs. Recently they added functions corresponding to the HTTP methods (GET, POST, etc.), but they don't support any form of authentication, and all you have access to is the lower-level Node request and response objects, so you'll be forced to learn how to work with those. Once you do, you'll find that there is some repetitive work to be done in each endpoint, like creating responses with the proper headers and response codes. You'll also have to worry about CORS compliance if your API is being consumed from the browser.
Restivus is actually built on top of Iron Router, and provides a layer of authentication on endpoints. It also abstracts away the need for direct interaction with the Node request and response objects, although they're still there in case we've missed anything. So it's using all the awesomeness of Iron Router with a higher-level API for your coding pleasure. Restivus is great if you're already using Iron Router, since it won't add any additional dependency.
RestStop2:
I was actually using RestStop2 in a project I'm working on when it was deprecated in favor of Iron Router. They had solid documentation, and an API I preferred above the others. Per their suggestion, I built a new package on top of Iron Router, which is very much inspired by RestStop2. Restivus is now being endorsed on the RestStop2 GitHub page, so I think they agree that it's a worthy replacement.
Here's a little code snippet from the Quick Start section of the Restivus docs:
if(Meteor.isServer) {
Meteor.startup(function () {
// Global configuration
Restivus.configure({
useAuth: true,
prettyJson: true
});
// Generates: GET, POST on /api/users and GET, DELETE /api/users/:id for
// Meteor.users collection
Restivus.addCollection(Meteor.users, {
excludedEndpoints: ['deleteAll', 'put'],
routeOptions: {
authRequired: true
},
endpoints: {
post: {
authRequired: false
},
delete: {
roleRequired: 'admin'
}
}
});
// Maps to: POST /api/articles/:id
Restivus.addRoute('articles/:id', {authRequired: true}, {
post: {
roleRequired: ['author', 'admin'],
action: function () {
var article = Articles.findOne(this.urlParams.id);
if (article) {
return {status: "success", data: article};
}
return {
statusCode: 400,
body: {status: "fail", message: "Unable to add article"}
};
}
}
});
});
}
Anyone stumbling across this now (2013+), checkout the Meteor Router smart package, which provides methods for server side routing useful in creating RESTful interfaces.
Meteor.Router.add('/404', [404, "There's nothing here!"]);
To assist you in future searches, be sure to take a look at https://atmosphere.meteor.com - a smart package repository. And Meteorite is a pretty handy CLI tool for version and package management.
The most elegant solution appears to be HTTP.publish. Rather than invent a new API like the others, it simply adds the HTTP protocol to the existing Meteor publish
interface. This means, for example, that Meteor.allow
and Meteor.deny
work automatically for HTTP as well as DDP.
Example:
If handed a collection and a publish function the
HTTP.publish
will mount on the following URLs and methods:GET - /api/list - all published data
POST - /api/list - insert a document into collection
GET - /api/list/:id - find one published document
PUT - /api/list/:id - update a document
DELETE - /api/list/:id - remove a document
myCollection = new Meteor.Collection('list');
// Add access points for `GET`, `POST`, `PUT`, `DELETE`
HTTP.publish(myCollection, function(data) {
// this.userId, this.query, this.params
return myCollection.find({});
});
It does not yet handle authentication completely.
Yes, you can expose REST endpoints with Meteor using the private API. The functionality will become public soon, but in the meantime, see Can I mount another route handler through ____meteor_bootstrap____.app?.
I know this is an old topic, but instead of using any external package, you can use the Meteor WebApp package: https://docs.meteor.com/packages/webapp.html.
Hope it helps!
I thought I would update the conversation for 2014. I still haven’t found the perfect way to implement REST services in Meteor and I’m hoping someone can point me in another direction to investigate. I’ve tested 3 projects and each have their drawbacks:
meteor-router I worked with meteor-router but the github page says it will only be fixing bugs going forward and to use Iron Router on all new projects. I’m still considering using this since if it works for me as-is then upgrades aren’t necessary except for some type of authentication.
iron-router I have a simple example service built using Iron Router but it appears to support REST services even less than meteor-router and causes the server to crash if someone posts invalid json to rest endpoint.
meteor-collectionapi Exposes a REST api for basic CRUD operations are support but it doesn’t appear to support queries other than by id.