merest
Version:
Express based REST-full API for Mongoose models
356 lines (314 loc) • 15.1 kB
HTML
<html lang="en">
<head>
<meta charset="utf-8">
<title>Requests and Responses | Merest</title>
<script src="scripts/prettify/prettify.js"> </script>
<script src="scripts/prettify/lang-css.js"> </script>
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
</head>
<body>
<div id="main">
<h1 class="page-title">Requests and Responses</h1>
<section>
<article>
<p><a name="requests_responses"></a></p>
<h3>End-points:</h3>
<h4>The paths of REST end-points:</h4><p>The end-point path consists of three parts:
/[<code>api-mount-path</code>/]<code>model-exposition-path</code>/[<code>additional-path</code>/]</p>
<ul>
<li><strong>api-mount-path</strong> -- the path that assigned in the <code>use</code> method called to
bind the ModelAPIExpress to your main application. This path could be omitted
in two cases: 1) the path omitted in the <code>use</code> method, or 2) the ModelAPIExpress
is main application (it's also possible)</li>
<li><strong>model-exposition-path</strong> - by default it is the collection name of exposed
Model. This path could be overrided by assigning <code>path</code> api-option on the
Model-routes level (see API-configuration)</li>
<li><strong>additional-path</strong> - by default it is omitted. It could be assigned by
specifying <code>path</code> api-option on the end-point level (see API-configuration)</li>
</ul>
<p><strong>merest</strong> grants that assigned by default paths for different end-points are not
intercepted, but it doesn't control the interception for custom assigned paths.</p>
<p><a name="common_responses"></a></p>
<h3>Common responses</h3><h5>404 - Document was not found (or doesn't exist)</h5><p><strong>merest</strong> returns this response if it couldn't find the Document (including
just created) by id in the url and/or doesn't match the assigned <code>filter</code>
api-option</p>
<pre class="prettyprint source lang-shell"><code>Status: 404
Content-Type: application/json; charset=utf-8
{"error": true, "code": 404, "message": "..."}</code></pre><h5>405 - End-point is not supported:</h5><p><strong>merest</strong> returns this response if requested path doesn't associated with any
handler.</p>
<p><strong>Note</strong>: instead of common practice for HTTP <strong>merest</strong> return 405 HTTP Response
code, but not 404 that means: Document was not found (or doesn't exist).</p>
<pre class="prettyprint source lang-shell"><code>Status: 405
Content-Type: application/json; charset=utf-8
{"error": true, "code": 405, "message": "Not Supported"}</code></pre><h5>422 - Validation error</h5><pre class="prettyprint source lang-shell"><code>Status: 422
Content-Type: application/json; charset=utf-8
{
"error": true,
"code": 422,
"message": "..."
[,"errors": {
...
}]
[,"stack": [
...
]]
}</code></pre><p>The fields <code>errors</code> and <code>stack</code> are optional.</p>
<p><a name="ep_options"></a></p>
<hr>
<h3>End-point <code>options</code>:</h3><p>Returns list of available end-points with short description.</p>
<p>Request:</p>
<pre class="prettyprint source lang-shell"><code>OPTIONS /end-point-path/ HTTP/1.1
HOST: hostname:port</code></pre><p>If you client doesn't support OPTIONS HTTP-method directly, use this message:</p>
<pre class="prettyprint source lang-shell"><code>POST /end-point-path/ HTTP/1.1
HOST: hostname:port
X-HTTP-Method-Override: OPTIONS</code></pre><p>Responses:</p>
<p>Success:</p>
<pre class="prettyprint source lang-shell"><code>Status: 200
Content-Type: application/json; charset=utf-8
[
["method", "path", "descriptions"],
["method", "path", "descriptions"],
...
["method", "path", "descriptions"]
]</code></pre><p>Other responses:</p>
<ul>
<li>405 - End-point is not supported</li>
</ul>
<p><a name="ep_search"></a></p>
<hr>
<h3>End-point <code>search</code>:</h3><p>Returns the list of Documents that satisfy query passed to call.</p>
<p>Request for end-point mounted on <code>GET</code>:</p>
<pre class="prettyprint source lang-shell"><code>GET /end-point-path/[?field1=value1&field2=value2&_sort=fieldName&_limit=number&_skip=number] HTTP/1.1
HOST: hostname:port</code></pre>
<p>Query String could contain pares field=value separated by the <code>&</code>.
Since the <strong>merest</merest> v. 1.2.0 the extended search opportunties is avaliable:
<ul>
<li>field<strong>__ne</strong>=value - the field is not equal to the value</li>
<li>field<strong>__in</string>=value,value,value - the field is one of the list of values (separated by coma)</li>
<li>field<strong>__nin</string>=value,value,value - the field is not in the list of values (separated by coma)</li>
<li>field<strong>__gt</strong>=value - the field is greater then the value</li>
<li>field<strong>__gte</strong>=value - the field is greater then or equal to the value</li>
<li>field<strong>__lt</strong>=value - the field is less then the value</li>
<li>field<strong>__lte</strong>=value - the field is less then or equal to the value</li>
<li>field<strong>__re</strong>=reg-exp - the field matches the pattern</li>
<li>field<strong>__ex</strong>=flag - the field exists (if flag is 1, true etc.) or doesn't exists (if flag is 0 or false)</li>
</ul>
<p>Also query string could contain three additional parameters:</p>
<ul>
<li>_sort=fieldName</li>
<li>_limit=maximum number of documents in Response</li>
<li>_skip=number of document that should be skipped in Response</li>
</ul>
<p>These parameters (all of them or any of them) will be ignored if
appropriate API-configuration option will be assigned to <code>false</code></p>
<p>To use all <strong>MongoDB</strong> query opportunities you could mount the <code>create</code> end-point
on the POST HTTP-method and specify <code>additional-path</code>.</p>
<p>In security reasons I don't recommend to do so. The better way is to extend Model
with static methods that accepts only necessary parameters and builds safe query.
However <strong>merest</strong> allows you to mount <code>search</code> end-point on POST method and
form query on the client-side.</p>
<p>Request for end-point mounted on <code>POST</code>:</p>
<pre class="prettyprint source lang-shell"><code>POST /end-point-path/[?_sort=fieldName&_limit=number&_skip=number] HTTP/1.1
HOST: hostname:port
Content-Type: application/json
<Mongoose Query-Object></code></pre><p>Success:</p>
<pre class="prettyprint source lang-shell"><code>Status: 200
Content-Type: application/json; charset=utf-8
[
{ ... },
{ ... }
...
{ ... }
]</code></pre><p>If no one Document found, the <strong>merest</strong> returns empty Array</p>
<p>Other responses:</p>
<ul>
<li>405 - End-point is not supported</li>
</ul>
<p><a name="ep_create"></a></p>
<hr>
<h3>End-point <code>create</code>:</h3><p>Creates new Document, finds it and returns to the client.</p>
<p>Request:</p>
<pre class="prettyprint source lang-shell"><code>POST /end-point-path/ HTTP/1.1
HOST: hostname:port
Content-Type: application/json
<Mongoose Model Object></code></pre><p>Responses:</p>
<p>Success:</p>
<pre class="prettyprint source lang-shell"><code>Status: 200
Content-Type: application/json; charset=utf-8
{ ... }</code></pre><p>406 - Method doesn't allow to update object</p>
<pre class="prettyprint source lang-shell"><code>Status: 406
Content-Type: application/json; charset=utf-8
{
"error": true,
"code": 406,
"message": "This method doesn't allow to update a(n) ${Model.name}"
}</code></pre><p>Other responses:</p>
<ul>
<li>404 - Document was not found (or doesn't exist)</li>
<li>405 - End-point is not supported</li>
<li>422 - Validation error</li>
</ul>
<p>The Response with status code 404 could be returned if created object doesn't
match <code>filter</code> api-option specified on the exposition.</p>
<p><a name="ep_details"></a></p>
<hr>
<h3>End-point <code>details</code>:</h3><p>Returns Document of the exposed Model by its id specified in the URL.</p>
<p>Request:</p>
<pre class="prettyprint source lang-shell"><code>GET /end-point-path/:id HTTP/1.1
HOST: hostname:port</code></pre><p>Responses:</p>
<p>Success:</p>
<pre class="prettyprint source lang-shell"><code>Status: 200
Content-Type: application/json; charset=utf-8
{ ... }</code></pre><p>Other responses:</p>
<ul>
<li>404 - Document was not found (or doesn't exist)</li>
<li>405 - End-point is not supported</li>
</ul>
<a name="ep_update"></a>
<hr>
<h3>End-point <code>update</code>:</h3><p>Updates the existing Document, returns it to the client.</p>
<p>Request:</p>
<pre class="prettyprint source lang-shell"><code>POST /end-point-path/:id HTTP/1.1
HOST: hostname:port
Content-Type: application/json
<Mongoose $set-object></code></pre><p>Responses:</p>
<p>Success:</p>
<pre class="prettyprint source lang-shell"><code>Status: 200
Content-Type: application/json; charset=utf-8
{ ... }</code></pre><p>Other responses:</p>
<ul>
<li>404 - Document was not found (or doesn't exist)</li>
<li>405 - End-point is not supported</li>
<li>422 - Validation error</li>
</ul>
<p><a name="ep_delete"></a></p>
<hr>
<h3>End-point <code>delete</code>:</h3><p>Finds Document by id specified in the URL, deletes it and returns empty
JSON-object to the client.</p>
<p>Request:</p>
<pre class="prettyprint source lang-shell"><code>DELETE /end-point-path/:id HTTP/1.1
HOST: hostname:port</code></pre><p>If you client doesn't support DELETE HTTP-method directly, use this message:</p>
<pre class="prettyprint source lang-shell"><code>POST /end-point-path/ HTTP/1.1
HOST: hostname:port
X-HTTP-Method-Override: DELETE</code></pre><p>Responses:</p>
<p>Success:</p>
<pre class="prettyprint source lang-shell"><code>Status: 200
Content-Type: application/json; charset=utf-8
{}</code></pre><p>Other responses:</p>
<ul>
<li>404 - Document was not found (or doesn't exist)</li>
<li>405 - End-point is not supported</li>
</ul>
<a name='transform-response'></a>
<h3>Response customization</h3><p><code>Merest</code> allows to customize all responses. In order to do that you should define
function that transforms prepared response and specify this function in api configuration</p>
<p><strong>Example</strong>:</p>
<pre class="prettyprint source lang-javascript"><code>// api.js
var api = new merest.ModelAPIExpress({
transformResponse: prepareResponse
});
...
function prepareResponse(req, res) {
var body = {
status: this.status,
data: this.body
};
this.status = 200;
this.body = body;
}</code></pre><p>You could access the following fields inside a transforming function:</p>
<ul>
<li><code>this.status</code> -- the HTTP Status</li>
<li><code>this.body</code> -- the response body</li>
<li><code>this.apiMethod</code> -- the API end-point name (<code>create</code>, <code>search</code>, <code>details</code> etc.)</li>
<li><code>this.apiInstanceMethod</code> -- the name of exposed instance method</li>
<li><code>this.apiStaticMethod</code> -- the name of exposed static method</li>
<li><code>this.api</code> -- the API-object (the child of <code>express</code>);</li>
<li><code>this.modelAPI</code> -- the router dispatches end-points related the model</li>
<li><code>this.model</code> -- the model name</li>
</ul>
<p>You should reassign <code>this.status</code> and <code>this.body</code> to override default HTTP-response.
The function returns nothing.</p>
<p>Calling API:</p>
<pre class="prettyprint source lang-shell"><code>curl -X OPTIONS http://localhost:1337/api/v1/</code></pre><p>Output:</p>
<pre class="prettyprint source lang-shell"><code>{
"status": 200,
"data": [
["options", "/api/v1/", "List all end-points of current application"],
["options", "/api/v1/vectors/", "List API-options for vectors"],
["get", "/api/v1/vectors/", "List/Search all vectors"],
["post", "/api/v1/vectors/", "Create a new Vector"],
["get", "/api/v1/vectors/:id", "Find a Vector by Id"],
["post", "/api/v1/vectors/:id", "Find a Vector by Id and update it (particulary)"],
["delete", "/api/v1/vectors/:id", "Find a Vector by Id and delete it."]
]
}</code></pre></li>
</ul>
<p>Also you can run this example:</p>
<pre class="prettyprint source lang-shell"><code>git clone https://github.com/DScheglov/merest.git
cd merest
npm install
node examples/transform-response/server.js</code></pre>
<br class="clear">
<hr>
<a href='installation.html'>Next (Installation) ></a>
</article>
</section>
</div>
<nav><h2>
<a href="index.html">merest</a>
</h2>
<h3><a href="installation.html">Installation</a></h3>
<ul>
<li><a href="installation.html#prerequisites">Prerequisites</a></li>
<li><a href="installation.html#npm-install">npm installation</a></li>
<li><a href="installation.html#development">Development</a></li>
</ul>
<h3><a href="cook-book.html">Cook-book</a></h3>
<h3><a href="conf-levels.html">API Configuration</a></h3>
<ul>
<li><a href="conf-levels.html">Configuration levels</a></li>
<li><a href="conf-app.html">API Application</a></li>
<li><a href="conf-router.html">Router</a></li>
<li><a href="conf-end-points.html">End-point</a></li>
<li><a href="conf-methods.html">Model methods</a></li>
</ul>
<h3><a href="end-points.html">API Requests and Responses</a></h3>
<ul>
<li><a href="end-points.html">Common reponses</a></li>
<li><a href="end-points.html#ep_options">Options</a></li>
<li><a href="end-points.html#ep_search">Search</a></li>
<li><a href="end-points.html#ep_create">Create</a></li>
<li><a href="end-points.html#ep_details">Details</a></li>
<li><a href="end-points.html#ep_update">Update</a></li>
<li><a href="end-points.html#ep_delete">Delete</a></li>
<li><a href="end-points.html#transform-response">Custom response</a></li>
</ul>
<h3><a href="swagger.html">Swagger support</a></h3>
<ul>
<li><a href="swagger.html#install">Installation</a></li>
<li><a href="swagger.html#api-conf">Configure API</a></li>
<li><a href="swagger.html#document">Creating <code>swagger.json</code></a></li>
<li><a href="swagger.html#api-docs">Exposing the api-docs</a></li>
<li><a href="swagger.html#swagger-ui">Embedded swagger-ui</a></li>
</ul>
<h3>Specifications</h3>
<ul>
<li><a href="ModelAPIExpress.html">ModelAPIExpress</a></li>
<li><a href="merest-swagger.html">Swagger-support methods</a></li>
<li><a href="ModelAPIRouter.html">ModelAPIRouter</a></li>
<li><a href="ModelAPIError.html">ModelAPIError</a></li>
</ul>
</nav>
<br class="clear">
<footer>
Documentation generated with <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a>
</footer>
<script> prettyPrint(); </script>
<script src="scripts/linenumber.js"> </script>
</body>
</html>