Restivus makes building REST APIs in Meteor 0.9.0+ easier than ever before! The package is inspired by RestStop2 and Collection API, and is built on top of Iron Router's server-side routing to provide:
- A simple interface for creating REST APIs
- Easily setup CRUD endpoints for Mongo Collections
- User authentication via the API
- Optional login and logout endpoints
- Access to
this.user
in authenticated endpoints - Custom authentication if needed
- Role permissions for limiting access to specific endpoints
- Works alongside the
alanning:roles
package - Meteor's accepted role permission package
- Works alongside the
- And coming soon:
- Basic versioning of routes and endpoints
- JSON PATCH support on collections
- Autogenerated OPTIONS endpoint on routes
- Pre and post hooks on all endpoints
You can install Restivus using Meteor's package manager:
> meteor add nimble:restivus
And to update Restivus to the latest version:
> meteor update nimble:restivus
Items = new Mongo.Collection 'items'
if Meteor.isServer
# Global API configuration
Restivus.configure
useAuth: true
prettyJson: true
# Generates: GET, POST, DELETE on /api/items and GET, PUT, DELETE on
# /api/items/:id for Items collection
Restivus.addCollection Items
# 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: /api/posts/:id
Restivus.addRoute 'posts/:id', authRequired: true,
get: ->
post = Posts.findOne @urlParams.id
if post
status: 'success', data: post
else
statusCode: 404
body: status: 'fail', message: 'Post not found'
post:
roleRequired: ['author', 'admin']
action: ->
post = Posts.findOne @urlParams.id
if post
status: "success", data: post
else
statusCode: 400
body: status: "fail", message: "Unable to add post"
delete:
roleRequired: 'admin'
action: ->
if Posts.remove @urlParams.id
status: "success", data: message: "Item removed"
else
statusCode: 404
body: status: "fail", message: "Item not found"
Items = new Mongo.Collection('items');
if(Meteor.isServer) {
// Global API configuration
Restivus.configure({
useAuth: true,
prettyJson: true
});
// Generates: GET, POST, DELETE on /api/items and GET, PUT, DELETE on
// /api/items/:id for Items collection
Restivus.addCollection(Items);
// 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: /api/posts/:id
Restivus.addRoute('posts/:id', {authRequired: true}, {
get: function () {
var post = Posts.findOne(this.urlParams.id);
if (post) {
return {status: 'success', data: post};
}
return {
statusCode: 404,
body: {status: 'fail', message: 'Post not found'}
};
},
post: {
roleRequired: ['author', 'admin'],
action: function () {
var post = Posts.findOne(this.urlParams.id);
if (post) {
return {status: "success", data: post};
}
return {
statusCode: 400,
body: {status: "fail", message: "Unable to add post"}
};
}
},
delete: {
roleRequired: 'admin',
action: function () {
if (Posts.remove(this.urlParams.id)) {
return {status: "success", data: {message: "Item removed"}};
}
return {
statusCode: 404,
body: {status: "fail", message: "Item not found"}
};
}
}
});
}
- Upgrading from 0.5.x
- Upgrading from 0.6.0
- Terminology
- Writing a Restivus API
- Consuming a Restivus API
- Resources
Restivus v0.6.1 brings support for easily generating REST endpoints for your Mongo Collections, and with that comes a few API-breaking changes:
- The
Restivus.add()
method has been changed toRestivus.addRoute()
for clarity, now that theRestivus.addCollection()
method has been added. - All responses generated by Restivus now follow the JSend format, with one minor tweak: failures have an identical structure to errors (check out the JSend documentation for more details on the response structure, which will be demonstrated throughout these docs). Just to be clear, this only affects responses that are automatically generated by Restivus. Any responses you manually created will remain unaffected.
Please see the change log for more information about the changes between each version.
WARNING! Do not use v0.6.0! Please upgrade to v0.6.1 or above.
v0.6.0 does not allow you to work with existing collections, or access collections created in
Restivus elsewhere in your app, which is not the intended behavior. Since Meteor expects you to
construct each collection only once (using new Mongo.Collection()
), and store that globally,
Restivus now requires that you pass an existing collection in Restivus.addCollection()
. Please
check out the updated section on defining collection routes for a
detailed breakdown of the parameters to Restivus.addCollection()
.
Just to clarify some terminology that will be used throughout these docs:
(HTTP) Method:
- The type of HTTP request (e.g., GET, PUT, POST, etc.)
Endpoint:
- The function executed when a request is made at a given URL path for a specific HTTP method
Route:
- A URL path and its set of configurable endpoints
The following configuration options are available with Restivus.configure
(must be called once,
but all properties are optional):
- String
- Default:
'api/'
- The base path for your API. If you use
'api'
and add a route called'users'
, the URL will behttps://yoursite.com/api/users/
.
- Object
- Default:
{ 'Content-Type': 'application/json' }
- The response headers that will be returned from every endpoint by default. These can be overridden
by returning
headers
of the same name from any endpoint.
- Boolean
- Default:
false
- If
true
,POST /login
andGET /logout
endpoints are added to the API. You can accessthis.user
andthis.userId
in authenticated endpoints.
- Object
token
String- Default:
'services.resume.loginTokens.token'
- The path to the auth token in the
Meteor.user
document. This location will be checked for a matching token if one is returned inauth.user()
.
- Default:
user
Function-
Default: Get user ID and auth token from
X-User-Id
andX-Auth-Token
headersfunction() { return { userId: this.request.headers['x-user-id'], token: this.request.headers['x-auth-token'] }; }
-
Provides one of two levels of authentication, depending on the data returned. The context within this function is the endpoint context without
this.user
andthis.userId
(well, that's what we're working on here!). Once the user authentication completes successfully, the authenticated user and their ID will be attached to the endpoint context. The two levels of custom authentication and their required return data are:- Partial auth
userId
: The ID of the user being authenticatedtoken
: The auth token to be verified- If both a
userId
andtoken
are returned, authentication will succeed if thetoken
exists in the givenMeteor.user
document at the location specified inauth.token
- Complete auth
user
: The fully authenticatedMeteor.user
- This is your chance to completely override the user authentication process. If a
user
is returned, anyuserId
andtoken
will be ignored, as it's assumed that you have already successfully authenticated the user (by whatever means you deem necessary). The given user is simply attached to the endpoint context, no questions asked.
- Partial auth
-
- Boolean
- Default:
false
- If
true
, render formatted JSON in response.
- Function
- Default:
undefined
- A hook that runs once a user has been successfully logged into their account via the
/login
endpoint. Context is the same as within authenticated endpoints. Any returned data will be added to the response body asdata.extra
(coming soon).
- Function
- Default:
undefined
- Same as onLoggedIn, but runs once a user has been successfully logged out of their account via
the
/logout
endpoint. Context is the same as within authenticated endpoints. Any returned data will be added to the response body asdata.extra
(coming soon).
- Boolean
- Default:
true
- If
false
, disable Iron Router on the client. This is recommended if you're not using Iron Router for your client-side routing. Note: Since this needs to be configured on the client, you must callRestivus.configure()
in a file available on both the client and server (e.g., common.js) for this to actually take effect.
Restivus.configure
useAuth: true
apiPath: 'my-api/'
prettyJson: true
auth:
token: 'auth.apiKey'
user: ->
userId: @request.headers['user-id']
token: @request.headers['login-token']
onLoggedIn: -> console.log "#{@user.username} (#{@userId}) logged in"
onLoggedOut: -> console.log "#{@user.username} (#{@userId}) logged out"
useClientRouter: false
- Boolean
- Default:
true
- If true, enables cross-origin resource sharing (CORS). This allows your API to receive requests
from any domain (when
false
, the API will only accept requests from the domain where the API is being hosted. Note: Only applies to requests originating from browsers).
One of the most common uses for a REST API is exposing a set of operations on your collections.
Well, you're in luck, because this is almost too easy with Restivus! All available REST endpoints
(except patch
and options
, for now) can be generated for a Mongo Collection using
Restivus.addCollection()
. This generates two routes by default:
/api/<collection>
- Operations on the entire collection
GET
,POST
, andDELETE
/api/<collection>/:id
- Operations on a single entity within the collection
GET
,PUT
, andDELETE
The first - and only required - parameter of Restivus.addCollection()
is a Mongo Collection.
Please check out the Meteor docs for more on creating
collections. The Meteor.users
collection will have [special endpoints]
(#users-collection-endpoints) generated.
Route and endpoint configuration options are available in Restivus.addCollection()
(as the 2nd,
optional parameter).
The top level properties of the options apply to both routes that will be generated
(/api/<collection>
and /api/<collection>/:id
):
- String
- Default: Name of the collection (the name passed to
new Mongo.Collection()
, or'users'
forMeteor.users
) - The base path for the generated routes. Given a path
'other-path'
, routes will be generated at'api/other-path'
and'api/other-path/:id'
- Object
authRequired
Boolean- Default:
false
- If true, all endpoints on these routes will return a
401
if the user is not properly authenticated.
- Default:
roleRequired
String or Array of Strings- Default:
undefined
(no role required) - The acceptable user roles for all endpoints on this route (e.g.,
'admin'
,['admin', 'dev']
). Additional role permissions can be defined on specific endpoints. If the authenticated user does not belong to at least one of the accepted roles, a401
is returned. Since a role cannot be verified without an authenticated user, setting theroleRequired
impliesauthRequired: true
, so that option can be omitted without any consequence. For more on setting up roles, check out thealanning:roles
package.
- Default:
- String or Array of Strings
- Default:
undefined
- The names of the endpoints that should not be generated (see the
endpoints
option below for a complete list of endpoint names).
- Object
- Default:
undefined
(all available endpoints generated) - Each property of this object corresponds to a REST endpoint. In addition to the
excludedEndpoints
list, you can also prevent an endpoint from being generated by setting its value tofalse
. All other endpoints will be generated. The complete set of configurable properties on these endpoints is described in the Endpoint Configuration section below. Here is a list of all available endpoints, including their corresponding HTTP method, path, and a short description of their behavior:getAll
EndpointGET /api/collection
- Return a list of all entities within the collection (filtered searching via query params coming soon!).
deleteAll
EndpointDELETE /api/collection
- Remove all entities in the collection. Be very careful with this endpoint! This should probably only be used for development or by users with a specific role, like 'admin'.
post
EndpointPOST /api/collection
- Add a new entity to the collection. All data passed in the request body will be copied into the newly created entity. Warning: This is unsafe for now, as no type or bounds checking is done.
get
EndpointGET /api/collection/:id
- Return the entity with the given
:id
.
put
EndpointPUT /api/collection/:id
- Completely replace the entity with the given
:id
with the data contained in the request body. Any fields not included will be removed from the document in the collection.
delete
EndpointDELETE /api/collection/:id
- Remove the entity with the given
:id
from the collection.
By default, each of the endpoints listed above is undefined
, which means it will be generated with
any default route options. If you need finer control over your endpoints, each can be defined as an
object containing the following properties:
- Boolean
- Default:
undefined
- If true, this endpoint will return a
401
if the user is not properly [authenticated] (#authenticating). If defined, this overrides the option of the same name defined on the entire route.
- String or Array of Strings
- Default:
undefined
(no role required) - The acceptable user roles for this endpoint (e.g.,
'admin'
,['admin', 'dev']
). These roles will be accepted in addition to any defined over the entire route. If the authenticated user does not belong to at least one of the accepted roles, a401
is returned. Since a role cannot be verified without an authenticated user, setting theroleRequired
impliesauthRequired: true
, so that option can be omitted without any consequence. For more on setting up roles, check out thealanning:roles
package.
- Function
- Default:
undefined
(Default endpoint generated) - If you need to completely override the default endpoint behavior, you can provide a function
that will be executed when the corresponding request is made. No parameters are passed; instead,
this
contains the endpoint context, with properties including the URL and query parameters.
All responses generated by Restivus follow the JSend format, with one minor tweak: failures have an identical structure to errors. Sample requests and responses for each endpoint are included below:
Request:
curl -X POST http://localhost:3000/api/posts/ -d "title=Witty Title" -d "author=Jack Rose"
Response:
{
"status": "success",
"data": {
"_id": "LrcEYNojn5N7NPRdo",
"title": "Witty Title",
"author": "Jack Rose"
}
}
Request:
curl -X GET http://localhost:3000/api/posts/
Response:
{
"status": "success",
"data": [
{
"_id": "LrcEYNojn5N7NPRdo",
"title": "Witty Title!",
"author": "Jack Rose",
},
{
"_id": "7F89EFivTnAcPMcY5",
"title": "Average Stuff",
"author": "Joe Schmoe",
}
]
}
Request:
curl -X DELETE http://localhost:3000/api/posts/
Response:
{
"status": "success",
"data": {
"message": "Removed 2 items"
}
}
Request:
curl -X GET http://localhost:3000/api/posts/LrcEYNojn5N7NPRdo
Response:
{
"status": "success",
"data": {
"_id": "LrcEYNojn5N7NPRdo",
"title": "Witty Title",
"author": "Jack Rose",
}
}
Request:
curl -X PUT http://localhost:3000/api/posts/LrcEYNojn5N7NPRdo -d "title=Wittier Title" -d "author=Jaclyn Rose"
Response:
{
"status": "success",
"data": {
"_id": "LrcEYNojn5N7NPRdo",
"title": "Wittier Title",
"author": "Jaclyn Rose"
}
}
Request:
curl -X DELETE http://localhost:3000/api/posts/LrcEYNojn5N7NPRdo
Response:
{
"status": "success",
"data": {
"message": "Item removed"
}
}
A few special exceptions have been made for routes added for the Meteor.users
collection. For now,
the majority of the operations are limited to read access to the user._id
and read/write access to
the user.profile
. All route and endpoint options are identical to those described for all other
collections above. No options have been configured in the examples below; however, it is highly
recommended that role permissions be setup (or at the absolute least, authentication required) for
the delete
and deleteAll
endpoints. Below are sample requests and responses for the users
collection.
Create collection:
Restivus.addCollection(Meteor.users);
Request:
POST http://localhost:3000/api/users
{
"email": "[email protected]",
"password": "password",
"profile": {
"firstName": "Jack",
"lastName": "Rose"
}
}
Note: The only fields that will be recognized in the request body when creating a new user are
email
, username
, password
, and profile
. These map directly to the parameters of the same
name in the Accounts.createUser() method, so
check that out for more information on how those fields are handled.
Response:
{
"status": "success",
"data": {
"_id": "oFpdgAMMr7F5A7P3a",
"profile": {
"firstName": "Jack",
"lastName": "Rose"
}
}
}
Request:
curl -X GET http://localhost:3000/api/users/
Response:
{
"status": "success",
"data": [
{
"_id": "nBTnv83sTrf38fFTi",
"profile": {
"firstName": "Anthony",
"lastName": "Reid"
}
},
{
"_id": "oFpdgAMMr7F5A7P3a",
"profile": {
"firstName": "Jack",
"lastName": "Rose"
}
}
]
}
Request:
curl -X DELETE http://localhost:3000/api/users/
Response:
{
"status": "success",
"data": {
"message": "Removed 2 users"
}
}
Request:
curl -X GET http://localhost:3000/api/users/oFpdgAMMr7F5A7P3a
Response:
{
"status": "success",
"data": {
"_id": "oFpdgAMMr7F5A7P3a",
"profile": {
"firstName": "Jack",
"lastName": "Rose"
}
}
}
Request:
PUT http://localhost:3000/api/users/oFpdgAMMr7F5A7P3a
{
"firstName": "Jaclyn",
"age": 25
}
Note: The data included in the request body will completely overwrite the user.profile
field of
the User document
Response:
{
"status": "success",
"data": {
"_id": "oFpdgAMMr7F5A7P3a",
"profile": {
"firstName": "Jaclyn",
"age": "25"
}
}
}
Request:
curl -X DELETE http://localhost:3000/api/users/oFpdgAMMr7F5A7P3a
Response:
{
"status": "success",
"data": {
"message": "User removed"
}
}
Routes are defined using Restivus.addRoute()
. A route consists of a path and a set of endpoints
defined at that path.
The path
is the 1st parameter of Restivus.addRoute
. You can pass it a string or regex. If you
pass it test/path
, the full path will be https://yoursite.com/api/test/path
.
Paths can have variable parameters. For example, you can create a route to show a post with a
specific id. The id
is variable depending on the post you want to see such as "/posts/1" or
"/posts/2". To declare a named parameter in the path, use the :
syntax followed by the parameter
name. When a user goes to that url, the actual value of the parameter will be stored as a property
on this.urlParams
in your endpoint function.
In this example we have a parameter named _id
. If we navigate to the /post/5
url in our browser,
inside of the GET endpoint function we can get the actual value of the _id
from
this.urlParams._id
. In this case this.urlParams._id => 5
.
# Given a url like "/post/5"
Restivus.addRoute '/post/:_id',
get: ->
id = @urlParams._id # "5"
// Given a url "/post/5"
Restivus.addRoute('/post/:_id', {
get: function () {
var id = this.urlParams._id; // "5"
}
});
You can have multiple URL parameters. In this example, we have an _id
parameter and a commentId
parameter. If you navigate to the url /post/5/comments/100
then inside your endpoint function
this.urlParams._id => 5
and this.urlParams.commentId => 100
.
# Given a url "/post/5/comments/100"
Restivus.addRoute '/post/:_id/comments/:commentId',
get: ->
id = @urlParams._id # "5"
commentId = @urlParams.commentId # "100"
// Given a url "/post/5/comments/100"
Restivus.addRoute('/post/:_id/comments/:commentId', {
get: function () {
var id = this.urlParams._id; // "5"
var commentId = this.urlParams.commentId; // "100"
}
});
If there is a query string in the url, you can access that using this.queryParams
.
# Given the url: "/post/5?q=liked#hash_fragment"
Restivus.addRoute '/post/:_id',
get: ->
id = @urlParams._id
query = @queryParams # query.q -> "liked"
// Given the url: "/post/5?q=liked#hash_fragment"
Restivus.addRoute('/post/:_id', {
get: function () {
var id = this.urlParams._id;
var query = this.queryParams; // query.q -> "liked"
}
});
The following options are available in Restivus.addRoute (as the 2nd, optional parameter):
- Boolean
- Default:
false
- If true, all endpoints on this route will return a
401
if the user is not properly authenticated.
- String or Array of Strings
- Default:
undefined
(no role required) - A string or array of strings corresponding to the acceptable user roles for all endpoints on
this route (e.g.,
'admin'
,['admin', 'dev']
). Additional role permissions can be defined on specific endpoints. If the authenticated user does not belong to at least one of the accepted roles, a401
is returned. Since a role cannot be verified without an authenticated user, setting theroleRequired
impliesauthRequired: true
, so that option can be omitted without any consequence. For more on setting up roles, check out thealanning:roles
package.
The last parameter of Restivus.addRoute is an object with properties corresponding to the supported HTTP methods. At least one method must have an endpoint defined on it. The following endpoints can be defined in Restivus:
get
post
put
patch
delete
options
These endpoints can be defined one of two ways. First, you can simply provide a function for each method you want to support at the given path. The corresponding endpoint will be executed when that type of request is made at that path.
For finer-grained control over each endpoint, you can also define each one as an object containing the endpoint action and some addtional configuration options.
An action
is required when configuring an endpoint. All other configuration settings are optional,
and will get their default values from the route.
- Function
- Default:
undefined
- A function that will be executed when a request is made for the corresponding HTTP method.
- String
- Default:
Route.authRequired
- If true, this endpoint will return a
401
if the user is not properly authenticated. Overrides the option of the same name defined on the entire route.
- String or Array of Strings
- Default:
Route.roleRequired
- The acceptable user roles for this endpoint (e.g.,
'admin'
,['admin', 'dev']
). These roles will be accepted in addition to any defined over the entire route. If the authenticated user does not belong to at least one of the accepted roles, a401
is returned. Since a role cannot be verified without an authenticated user, setting theroleRequired
impliesauthRequired: true
, so that option can be omitted without any consequence. For more on setting up roles, check out thealanning:roles
package.
Restivus.addRoute 'posts', {authRequired: true},
get:
authRequired: false
action: ->
# GET api/posts
post: ->
# POST api/posts
put: ->
# PUT api/posts
patch: ->
# PATCH api/posts
delete: ->
# DELETE api/posts
options: ->
# OPTIONS api/posts
Restivus.addRoute('posts', {authRequired: true}, {
get: function () {
authRequired: false
action: function () {
// GET api/posts
}
},
post: function () {
// POST api/posts
},
put: function () {
// PUT api/posts
},
patch: function () {
// PATCH api/posts
},
delete: function () {
// DELETE api/posts
},
options: function () {
// OPTIONS api/posts
}
});
In the above examples, all the endpoints except the GETs will require [authentication] (#authenticating).
Each endpoint has access to:
- Meteor.user
- The authenticated
Meteor.user
. Only available ifuseAuth
andauthRequired
are bothtrue
. If not, it will beundefined
.
- String
- The authenticated user's
Meteor.userId
. Only available ifuseAuth
andauthRequired
are bothtrue
. If not, it will beundefined
.
- Object
- Non-optional parameters extracted from the URL. A parameter
id
on the pathposts/:id
would be available asthis.urlParams.id
.
- Object
- Optional query parameters from the URL. Given the url
https://yoursite.com/posts?likes=true
,this.queryParams.likes => true
.
- Object
- Parameters passed in the request body. Given the request body
{ "friend": { "name": "Jack" } }
,this.bodyParams.friend.name => "Jack"
.
- Node response object
- If you handle the response yourself using
this.response.write()
orthis.response.writeHead()
you must callthis.done()
. In addition to preventing the default response (which will throw an error if you've initiated the response yourself), it will also close the connection usingthis.response.end()
, so you can safely omit that from your endpoint.
-
Function
-
Must be called after handling the response manually with
this.response.write()
orthis.response.writeHead()
. This must be called immediately before returning from an endpoint.Restivus.addRoute('manualResponse', { get: function () { console.log('Testing manual response'); this.response.write('This is a manual response'); this.done(); // Must call this immediately before return! } });
All endpoint configuration options can be accessed by name (e.g.,
this.roleRequired
). Within an endpoint, all options have been completely resolved, meaning all
configuration options set on an endpoint's route will already be applied to the endpoint as
defaults. So if you set authRequired: true
on a route and do not set the authRequired
option on
one if its endpoints, this.authRequired
will still be true
within that endpoint, since the
default will already have been applied from the route.
You can return a raw string:
return "That's current!";
A JSON object:
return { json: 'object' };
A raw array:
return [ 'red', 'green', 'blue' ];
Or include a statusCode
or headers
. At least one must be provided along with the body
:
return {
statusCode: 404,
headers: {
'Content-Type': 'text/plain',
'X-Custom-Header': 'custom value'
},
body: {
status: 'success',
data: {
message: 'There is nothing here!'
}
}
};
All responses contain the following defaults, which will be overridden with any provided values:
- Default:
200
- Default:
Content-Type
:application/json
Access-Control-Allow-Origin
:*
- This is a CORS-compliant header that allows requests to be made to the API from any domain. Without this, requests from within the browser would only be allowed from the same domain the API is hosted on, which is typically not the intended behavior. This can be disabled by default, or also by returning a header of the same name with a domain specified (usually the domain the API is being hosted on).
What's a REST API without awesome docs? I'll tell you: absolutely freaking useless. So to fix that, we use and recommend apiDoc. It allows you to generate beautiful and extremely handy API docs from your JavaScript or CoffeeScript comments. It supports other comment styles as well, but we're Meteorites, so who cares? Check it out. Use it.
The following uses the above code.
We can call our POST /posts/:id/comments
endpoint the following way. Note the /api/ in the URL
(defined with the api_path option above):
curl -d "message=Some message details" http://localhost:3000/api/posts/3/comments
If you have useAuth
set to true
, you now have a POST /api/login
endpoint that returns a
userId
and authToken
. You must save these, and include them in subsequent requests.
Warning: Make sure you're using HTTPS, otherwise this is insecure! In an ideal world, this should only be done with DDP and SRP, but, alas, this is a REST API.
curl http://localhost:3000/api/login/ -d "password=testpassword&user=test"
The response will look like this, which you must save (for subsequent authenticated requests):
{ status: "success", data: {authToken: "f2KpRW7KeN9aPmjSZ", userId: fbdpsNf4oHiX79vMJ} }
You also have an authenticated GET /api/logout
endpoint for logging a user out. If successful, the
auth token that is passed in the request header will be invalidated (removed from the user account),
so it will not work in any subsequent requests.
curl http://localhost:3000/api/logout -H "X-Auth-Token: f2KpRW7KeN9aPmjSZ" -H "X-User-Id: fbdpsNf4oHiX79vMJ"
For any endpoints that require the default authentication, you must include the userId
and
authToken
with each request under the following headers:
- X-User-Id
- X-Auth-Token
curl -H "X-Auth-Token: f2KpRW7KeN9aPmjSZ" -H "X-User-Id: fbdpsNf4oHiX79vMJ" http://localhost:3000/api/posts/
A detailed list of the changes between versions can be found in the [change log] (https://github.com/kahmali/meteor-restivus/blob/master/CHANGELOG.md).
Contributions to Restivus are welcome and appreciated! If you're interested in contributing, please check out the guidelines before getting started.
Thanks to the developers over at Differential for RestStop2, where we got our inspiration for this package and stole tons of ideas and code, as well as the Iron Router team for giving us a solid foundation with their server-side routing in Meteor.
Also, thanks to the following projects, which RestStop2 was inspired by:
MIT License. See LICENSE for details.