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 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.
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.
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.
Related
I've been building a lot of quick prototypes on Netlify lately. I love the service for its ease of setup and deployment. But I keep running into this conflict between their JAMstacky conventions around API endpoints and my own background in RESTful API design.
To be more specific, say I am building a basic CRUD API in which I can create, fetch one, fetch all, and update some resource type . Let's say a User. If I were designing those endpoints from a RESTful perspective, it would look like this:
POST /users -> Create a user
GET /users -> Fetch all users
GET /users/{id} -> Fetch one user
PUT /users/{id} -> Update a user
Now, if I were setting this up on AWS, perhaps with the serverless framework, each of those endpoints would be their own lambda. But Netlify offers no such configuration options. Which is mostly nice. I hate configuration. But it is difficult to achieve these endpoints at all with Netlify.
Specifically in this case, Netlify automatically creates endpoints which match filenames. So if you have a file named users.js, that creates a /users endpoint. The problem is, that file will be used for every possible permutation of /users. Every HTTP method. Every subroute. They all go to this one lambda. So in order to achieve a RESTful API design, I have to put everything in a single lambda and essentially make it a router. Which seems to defeat the whole idea of serverless.
So usually when you read Netlify examples, which claim to follow JAMstack patterns (something I'm not super familiar with), they do not use RESTful endpoints. Instead they tend to do something like this:
POST /create-user -> Create a user
GET /fetch-users -> Fetch all users
GET /fetch-user?id={id} -> Fetch one user
POST /update-user -> Update a user
So this is in some ways a Netlify question, and in some way a larger question about JAMstack patterns. Is there something inherent about JAMstack that makes it incompatible with REST? Are there different conventions which tend to replace REST for Netflify/JAMstack projects?
"Is there something inherent about JAMstack that makes it incompatible with REST?"
I would say no as it's not related. You aren't building an API with the Jamstack. You are using a service (Netlify) which supports serverless functions that operate alongside the rest of your site. Remember that the Netlify serverless functions are just one option. You could set up your own AWS setup and support the mechanism you want, and still use it in conjunction with the rest of your Jamstack site. I like Netlify's serverless stuff, but it's not going to work for 100% of the use cases out there.
I guess my tl;dr is - Netlify tried to make serverless simple for folks building Jamstack sites, but it won't cover every use case. When it doesn't, you can still use your own solutions along with your site.
I am currently evaluating the framework "wolkenkit" [1] for using it in an application. Within this application I will have a user interface for tenant-based data management. Only authenticated users will have access to this application.
Additionally there should be a public REST API following common standards and being callable by public (tenant security done with submission of a tenant-based API Key within the request headers).
As far as I have found out, the wolkenkit REST API does not seem to fit these standards in forms of HTTP verbs.
But as wolkenkit at all appears to me as a really flexible and easy-to-use framework, I wonder how to basically implement such a public API.
May it be e.g. a valid approach to create an own web application which internally connects to the wolkenkit backend? What about the additional performance overhead then?
[1] https://www.wolkenkit.io/
In addition to the answer of mattwagl, I would like to point out a few things that you may be interested in.
First of all, since wolkenkit is based on CQRS, the application has a separate API for writing and reading. That means, that if you send a command (whose intent is to change state) this goes to the write API. If you subscribe for events or run a query, this goes to the read API.
This again means, that if you send a command, it's up to the write side to respond to it. As the write side is not meant to return application state, all it says is basically: "Thanks, I have received the command." To get the actual result you have to wait for the appropriate event, which means subscribing to the read API.
In the wolkenkit documentation there is a nice diagram which shows this in a clear way:
If you now add a separate REST API (which actually fulfills the requirements of REST), this means that you need to handle waiting for the result internally. In other words: Clients in wolkenkit are always meant to be asynchronous, REST is not. Hence it's your job to handle the asynchronous behavior of the wolkenkit APIs in your REST API. I think that this is the hardest part.
Once you have done this, you will have a synchronous REST API, and of course it will have some overhead. But I think that since its overhead is limited to passing through and translating network requests, it should be negligible.
Oh, and finally, there is another thing that you have to watch out for: Since REST as it was meant originally relies on the HTTP verbs to transport semantics, you need to map GET / POST / PUT / DELETE to the semantic commands of wolkenkit. As long as this can be done 1:1, everything's fine – problems start when there are multiple commands that (technically speaking) do an UPDATE.
PS: I'm also one of the developers of wolkenkit.
PPS: However you are going to solve this, I would be highly interested to hear from you! It would be very great if you could share your experiences with us, as you are most probably not the last one with this idea. If you want to contact us, the easiest way would be via Slack.
wolkenkit applications can be accessed using an HTTP- and a Websocket-API. These APIs are both provided by the tailwind module that wolkenkit uses under the hood. In the tailwind repo you can find a very simple documentation of the available HTTP routes.
You're right, the wolkenkit HTTP-API is not a classic REST-API. It's more RPC-style which in our experience is a good fit for applications. There are only 3 routes that your clients/tenants need to support: /v1/command (POST) is used for issuing commands. The commands you post should follow the command schema. /v1/events (POST) can be used for streaming events to clients. These events will follow the event schema. Finally you have /v1/read/:modelType/:modelName (POST) to read models. You can simply use HTTPie to test these routes.
Authentication of these APIs is currently done using OpenID-Connect. There's a very detailed article on how to setup authentication using Auth0. I'm not quite sure if this fits your use-case but you could basically use any Authentication Service that follows this standard or that is able to issue JWT tokens.
Finally you could also build your own JavaScript client-SDK that runs inside browsers by building a module that uses the wolkenkit-client-js under the hood. This SDK can just use the same API as any other client to connect to your application.
Hope this helps.
PS: Please note that I am one of the authors of wolkenkit.
What are some web apps that allow me to play with any REST APIs visually (by clicking) and also get some code generated (in any language) that captures what I have described visually?
Similar to Swagger or Google API Playground but allows me to talk to anything that speaks REST (assuming I have the proper auth credentials and I know what messages it understands).
Bonus points for something that can also "discover" what messages are understood, given a URL endpoint.
Microsoft has 2 that I know of
OData API explorer
The data market service explorer (requires signing in, and then you can access free data sets)
Considering that REST API's are going to follow their own conventions, terms, and have their own documentation (hopefully), this is an impossible problem. If you restrict your quest to visualizing API's that follow a "standard" form of self-documentation (see REST web service WSDL? for some hopeful scenarios) you might be able to accomplish this.
Or you can use something like http://www.programmableweb.com/ to discover tutorials, tools, examples, and mashups of various existing APIs.
You could mock an API at http://apiary.io/.
You could explore and existing one through tools (e.g. REST Console for Chrome)
What you can't have, is one-size-fits-all explorer for "every possible REST API." Some APIs follow conventions that others don't.
apigee and apihub (now part of mulesoft) are two that I frequently visit. Of the two, apigee is my preferred provider.
One of the reasons that you're not going to see a lot of websites like this is because of the same-origin policy. This means that you can't access a RESTful API located at api.google.com from a web app running at, say, www.restfiddle.com without sending all the API traffic through restfiddle.com's servers. Sites like JSFiddle can exist (and are used widely) because all the processing is done on the client side.
Browser plugins, however, are exempt from the same-origin policy. If you're using Chrome, try Postman. If your REST client doesn't need to be web-based, check out SoapUI. IntelliJ IDEA has a nice REST client as well.
Try Restlet Studio, it's the only visual API designer I've found, and seems pretty good, it imports and exports swagger & RAML.
http://studio.restlet.com/
I'm, going to write a web app, which should be CRUD accessible from both, the web and native mobile device apps. For the latter i'm definitely committed to a REST API. Is it possible to realize that with Meteor.com ? Would it be an option to use Meteor for just the web and a second REST interface to directly talk to the mongo? Since the meteor client listens for changes in the mongodb this should not cause conflicts, does it?
As of 2015, look at Gadi's answer for the Meteorpedia entry on REST APIs, and at krose's answer comparing REST API packages. Discussion for folding REST APIs into core is on Hackpad. This question is a duplicate of How to expose a RESTful service with Meteor, which has much better answers. -- Dan Dascalescu
Old answer (2012) below.
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.
There are a lot of duplicates of this question. I did a full write-on on this in Meteorpedia which I believe covers all issues:
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.
If you are planning to develop a production application, then Meteor is not an option right now. Its under constant change, and there are still many common features it has to support before its ready to use, which will be quite some time.
For your Question, Somebody has already asked and answered the question about support for file uploading in meteor(also contains HTTP handing related information).
How would one handle a file upload with Meteor?
I'm working with NodeJS + Mongoose, writing a Single Page Application, so I need to serve some statics and then all the interaction between frontend and backend is done via XHR. Eventually I'm thinking about writing a native mobile app accessing the same backend. Is there any pattern / best practice I should apply here?, I thought that I may need to extract the API to be exposed via Restify, and handle the requests from the webapp only with ExpressJS? or should I just put all the stuff exposed via Restify? I guess my confusion comes from not being worked with Restify before, so any explanation about how is it different from ExpressJS (specially when talking about a Single Page App) is really welcome.
I am implementing a similar solution, mobile app & website with expressjs and backbonejs. I did not use restify because i did not think i needed the extra complexity, there were not that many API endpoints so expressjs handled everything ok for me.
BTW take a look at this post on restify performance, I just saw it today and have not personally validate the contents.
Benchmarking APIs using PerfectAPI vs Express.js vs Restify.js « « PerfectAPI Blog PerfectAPI Blog http://bit.ly/xrTguB
Restify is packaging DTrace and various handlers that Express doesn't. If you just have one API endpoint and don't need DTrace, it doesn't make sense to run Restify.
Also, you might want to try express-resource