simple:rest

v0.2.0Published 9 years ago

This package has not had recent updates. Please investigate it's current state before committing to using it in your project.

Current status: pre-1.0 preview release - it's stable, but might not have all of the features you need. Leave feedback in this Hackpad.

One-step JSON API for your publications and methods

meteor add simple:rest

Add this package to get an automatic JSON HTTP API for all of your Meteor app's publications and methods. It works with all of your existing security rules and authentication. This can be useful for many things:

  • Build a simple native mobile app on top of your Meteor app's data
  • Expose an API for other people to get data
  • Integrate with other frameworks and platforms without having to integrate a DDP client

Keep in mind that this package is literally calling your Meteor methods and publications. This means if you have any nice packages that do roles, authentication, permissions, etc. for your app, those packages should still work just fine over HTTP.

Table of contents

  1. Using the API
  2. Publications
  3. Methods
  4. Collection insert/update/remove
  5. Example code with JQuery
  6. Additional tools
  7. Listing all API methods
  8. Cross origin requests
  9. Authentication
  10. Logging in over HTTP
  11. Change log

Publications

By default, publications are accessible via an HTTP GET request at the URL:

GET /publications/<publication-name>

The response is an object where the keys are the collections in the publication, and each collection has an array of documents. Note that a publication can publish from many collections at once.

1{
2  collectionName: [
3    { _id: "xxx", otherData: "here" },
4    { _id: "yyy", otherData: "here" }
5  ]
6}

You can pass an option to Meteor.publish to set a custom URL, which can contain parameters. The parameters are in the form :argument-number, so in this case :0 means that segment of the URL will be passed as the first argument. Note that the arguments are always strings, so you might need to parse to get an integer if you are expecting one.

1Meteor.publish("widgets-above-index", function (index) {
2  return Widgets.find({index: {$gt: parseInt(index, 10)}});
3}, {
4  url: "widgets-with-index-above/:0"
5});

Call the above API with:

GET /widgets-with-index-above/4

Methods

By default, methods are accessible with a POST request at the following URL:

POST /methods/<method-name>

Arguments are passed as JSON or query-encoded data in the message body. Since the arguments are positional, the arguments are in array form. Here's an example of how you can call a method using Meteor's http package:

1HTTP.post("/methods/addNumbers", {
2  data: [2, 2]
3}, function (err, res) {
4  console.log(res); // 4
5});

You can pass a custom URL to a method by using an alternate method definition syntax that comes from this package, Meteor.method:

1Meteor.method("return-five", function () {
2  return 5;
3}, {
4  url: "return-five"
5});

Then you can call this method with:

POST /return-five

Collection methods

The default Meteor collection methods (insert, update, and remove) are also automatically exposed when this package is added. Don't worry, they follow the exact same security rules as in your Meteor DDP app, and allow/deny still works perfectly.

Inserting into a collection

POST /<collection-name>

The body of the request should be a JSON-serialized document to insert into the database.

Updating a document in a collection

PATCH /<collection-name>/<_id>

The body of the request should be a JSON-serialized set of fields to update in the document.

Deleting a document from a collection

DELETE /<collection-name>/<_id>

No request body is necessary for deletion, it just deletes the document with the specified _id.

Example code with JQuery

Here is how you might call your shiny new HTTP API using JQuery. Note that you must set contentType to "application/json", because by default JQuery uses form serialization rather than JSON serialization.

1// Calling a method
2$.ajax({
3  method: "post",
4  url: "/methods/add-all-arguments",
5  data: JSON.stringify([1, 2, 3]),
6  contentType: "application/json",
7  success: function (data) {
8    console.log(data); // 6
9  }
10});
11
12// Getting data from a publication
13$.get("/publications/widgets", function (data) {
14  console.log(data.widgets.length); // 11
15});

Listing all API methods

This package defines a special publication that publishes a list of all of your app's API methods. Call it like this:

GET /publications/api-routes

The result looks like:

1{
2  "api-routes": [
3    {
4      "_id": "get /publications/api-routes",
5      "method": "get",
6      "path": "/publications/api-routes"
7    },
8    {
9      "_id": "options /users/login",
10      "method": "options",
11      "path": "/users/login"
12    },
13    {
14      "_id": "post /users/login",
15      "method": "post",
16      "path": "/users/login"
17    },
18    {
19      "_id": "options /users/register",
20      "method": "options",
21      "path": "/users/register"
22    },
23    {
24      "_id": "post /users/register",
25      "method": "post",
26      "path": "/users/register"
27    },
28    {
29      "_id": "options /methods/lists/insert",
30      "method": "options",
31      "path": "/methods/lists/insert"
32    },
33    ...
34  ]
35}

Note that this package also generates OPTIONS endpoints for all of your methods. This is to allow you to enable cross-origin requests if you choose to, by returning an Access-Control-Allow-Origin header. More on that below.

Cross-origin requests

If you would like to use your API from the client side of a different app, you need to return a special header. You can do this by hooking into a method on the simple:json-routes package, like so:

1// Enable cross origin requests for all endpoints
2JsonRoutes.setResponseHeaders({
3  "Cache-Control": "no-store",
4  "Pragma": "no-cache",
5  "Access-Control-Allow-Origin": "*",
6  "Access-Control-Allow-Methods": "GET, PUT, POST, DELETE, OPTIONS",
7  "Access-Control-Allow-Headers": "Content-Type, Authorization, X-Requested-With"
8});

Authentication

API endpoints generated with this package accept a standard bearer token header (Based on RFC 6750 and OAuth Bearer).

Authorization: Bearer <token>

Here is how you could use Meteor's http package to call a method as a logged in user. Inside the method, the current user can be accessed the exact same way as in a normal method call, through this.userId.

1HTTP.post("/methods/return-five-auth", {
2  headers: { Authorization: "Bearer " + token }
3}, function (err, res) {
4  console.log(res.data); // 5
5});

Logging in over HTTP

This package allows you to authenticate API calls using a token, but does not provide methods to get that token over HTTP. Use the following packages to log in over HTTP:

Change log

0.2.0

Changed api for insert/update/remove to be more RESTful. Now you call it with:

POST /collection
PATCH /collection/:_id
DELETE /collection/:_id

0.1.2

Initial publicized release