Skip to content

Instantly share code, notes, and snippets.

@tediscript
Created June 6, 2014 10:22
Show Gist options
  • Save tediscript/717c85f34f56e5e0fc9f to your computer and use it in GitHub Desktop.
Save tediscript/717c85f34f56e5e0fc9f to your computer and use it in GitHub Desktop.
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<title>JSend</title><link rel="start" href="/labs/jsend/wiki" /><link rel="search" href="/labs/jsend/search" /><link rel="help" href="/labs/jsend/wiki/TracGuide" /><link rel="stylesheet" href="/labs/css/trac.css" type="text/css" /><link rel="stylesheet" href="/labs/css/wiki.css" type="text/css" /><link rel="icon" href="/favicon.ico" type="image/x-icon" /><link rel="shortcut icon" href="/favicon.ico" type="image/x-icon" /><link rel="alternate" href="/labs/jsend/wiki/WikiStart?format=txt" title="Plain Text" type="text/x-trac-wiki" /><style type="text/css">
</style>
<script type="text/javascript" src="/labs/js/trac.js"></script>
</head>
<body>
<div id="banner">
<div id="header"><a id="logo" href="https://labs.omniti.com/"><img src="/images/logo_labs.gif" alt="" /></a><hr /></div>
<form id="search" action="/labs/jsend/search" method="get">
<div>
<label for="proj-search">Search:</label>
<input type="text" id="proj-search" name="q" size="10" accesskey="f" value="" />
<input type="submit" value="Search" />
<input type="hidden" name="wiki" value="on" />
<input type="hidden" name="changeset" value="on" />
<input type="hidden" name="ticket" value="on" />
</div>
</form>
<div id="metanav" class="nav"><ul><li id="metanav_login" class="first"><a href="/labs/jsend/login">Login</a></li><li id="metanav_settings" ><a href="/labs/jsend/settings">Settings</a></li><li id="metanav_help" ><a accesskey="6" href="/labs/jsend/wiki/TracGuide">Help/Guide</a></li><li id="metanav_about" class="last"><a href="/labs/jsend/about">About Trac</a></li></ul></div>
</div>
<div id="mainnav" class="nav"><ul><li id="mainnav_wiki" class="active first"><a accesskey="1" href="/labs/jsend/wiki">Wiki</a></li><li id="mainnav_timeline" ><a accesskey="2" href="/labs/jsend/timeline">Timeline</a></li><li id="mainnav_roadmap" ><a accesskey="3" href="/labs/jsend/roadmap">Roadmap</a></li><li id="mainnav_browser" ><a href="/labs/jsend/browser">Browse Source</a></li><li id="mainnav_tickets" ><a href="/labs/jsend/report">View Tickets</a></li><li id="mainnav_search" class="last"><a accesskey="4" href="/labs/jsend/search">Search</a></li></ul></div>
<div id="main">
<div id="ctxtnav" class="nav">
<h2>Wiki Navigation</h2>
<ul>
<li><a href="/labs/jsend/wiki">Start Page</a></li>
<li><a href="/labs/jsend/wiki/TitleIndex">Index by Title</a></li>
<li><a href="/labs/jsend/wiki/RecentChanges">Index by Date</a></li>
<li class="last"><a href="/labs/jsend/wiki/WikiStart?action=diff&amp;version=13">Last Change</a></li>
</ul>
<hr />
</div>
<div id="content" class="wiki">
<div class="wikipage">
<div id="searchable"><h1 id="JSend">JSend</h1>
<ul><li><strong>What?</strong> - Put simply, JSend is a specification that lays down some rules for how <a class="ext-link" href="http://json.org"><span class="icon">JSON</span></a> responses from web servers should be formatted. JSend focuses on application-level (as opposed to protocol- or transport-level) messaging which makes it ideal for use in <a class="ext-link" href="http://en.wikipedia.org/wiki/Representational_State_Transfer"><span class="icon">REST</span></a>-style applications and APIs.
</li></ul><ul><li><strong>Why?</strong> - There are lots of web services out there providing JSON data, and each has its own way of formatting responses. Also, developers writing for <a class="missing wiki" href="/labs/jsend/wiki/JavaScript" rel="nofollow">JavaScript?</a> front-ends continually re-invent the wheel on communicating data from their servers. While there are many common patterns for structuring this data, there is no consistency in things like naming or types of responses. Also, this helps promote happiness and unity between backend developers and frontend designers, as everyone can come to expect a common approach to interacting with one another.
</li></ul><ul><li><strong>Hold on now, aren't there already specs for this kind of thing?</strong> - Well... no. While there are a few handy specifications for dealing with JSON data, most notably <a class="ext-link" href="http://www.crockford.com/"><span class="icon">Douglas Crockford</span></a>'s <a class="ext-link" href="http://www.json.org/JSONRequest.html"><span class="icon">JSONRequest</span></a> proposal, there's nothing to address the problems of general application-level messaging. More on this later.
</li></ul><ul><li><strong>(Why) Should I care?</strong> - If you're a library or framework developer, this gives you a consistent format which your users are more likely to already be familiar with, which means they'll already know how to consume and interact with your code. If you're a web app developer, you won't have to think about how to structure the JSON data in your application, and you'll have existing reference implementations to get you up and running quickly.
</li></ul><ul><li><strong>Discuss</strong> - <a class="ext-link" href="http://lists.omniti.com/mailman/listinfo/jsend-users"><span class="icon">Mailing list</span></a>
</li></ul><h2 id="Sohowsitwork">So how's it work?</h2>
<p>
A basic JSend-compliant response is as simple as this:
</p>
<pre class="wiki">{
status : "success",
data : {
"post" : { "id" : 1, "title" : "A blog post", "body" : "Some useful content" }
}
}
</pre><p>
When setting up a JSON API, you'll have all kinds of different types of calls and responses. JSend separates responses into some basic types, and defines required and optional keys for each type:
</p>
<table class="wiki">
<tr><td><strong>Type</strong></td><td><strong>Description</strong></td><td><strong>Required Keys</strong></td><td><strong>Optional Keys</strong>
</td></tr><tr><td>success</td><td>All went well, and (usually) some data was returned.</td><td>status, data</td><td>
</td></tr><tr><td>fail</td><td>There was a problem with the data submitted, or some pre-condition of the API call wasn't satisfied</td><td>status, data</td><td>
</td></tr><tr><td>error</td><td>An error occurred in processing the request, i.e. an exception was thrown</td><td>status, message</td><td>code, data
</td></tr></table>
<h2 id="Exampleresponsetypes">Example response types</h2>
<p>
<strong>Success</strong>: When an API call is successful, the JSend object is used as a simple envelope for the results, using the <tt>data</tt> key, as in the following:
</p>
<p>
<strong><tt>GET /posts.json</tt>:</strong>
</p>
<pre class="wiki">{
status : "success",
data : {
"posts" : [
{ "id" : 1, "title" : "A blog post", "body" : "Some useful content" },
{ "id" : 2, "title" : "Another blog post", "body" : "More content" },
]
}
}
</pre><p>
<strong><tt>GET /posts/2.json</tt>:</strong>
</p>
<pre class="wiki">{
status : "success",
data : { "post" : { "id" : 2, "title" : "Another blog post", "body" : "More content" }}
}
</pre><p>
<strong><tt>DELETE /posts/2.json</tt>:</strong>
</p>
<pre class="wiki">{
status : "success",
data : null
}
</pre><p>
Required keys:
</p>
<ul><li>status: Should always be set to "success".
</li><li>data: Acts as the wrapper for any data returned by the API call. If the call returns no data (as in the last example), data should be set to null.
</li></ul><p>
<strong>Fail</strong>: When an API call is rejected due to invalid data or call conditions, the JSend object's data key contains an object explaining what went wrong, typically a hash of validation errors. For example:
</p>
<p>
<strong><tt>POST /posts.json</tt></strong> (with data <strong><tt>body: "Trying to creating a blog post"</tt></strong>):
</p>
<pre class="wiki">{
"status" : "fail",
"data" : { "title" : "A title is required" }
}
</pre><p>
Required keys:
</p>
<ul><li>status: Should always be set to "fail".
</li><li>data: Again, provides the wrapper for the details of why the request failed. If the reasons for failure correspond to <tt>POST</tt> values, the response object's keys SHOULD correspond to those <tt>POST</tt> values.
</li></ul><p>
<strong>Error</strong>: When an API call fails due to an error on the server. For example:
</p>
<p>
<strong><tt>GET /posts.json</tt></strong>:
</p>
<pre class="wiki">{
"status" : "error",
"message" : "A title is required"
}
</pre><p>
Required keys:
</p>
<ul><li>status: Should always be set to "error".
</li><li>message: A meaningful, end-user-readable (or at the least log-worthy) message, explaining what went wrong.
</li></ul><p>
Optional keys:
</p>
<ul><li>code: A numeric code corresponding to the error, if applicable
</li><li>data: A generic container for any other information about the error, i.e. the conditions that caused the error, stack traces, etc.
</li></ul><p>
</p>
<h2 id="WhitherHTTP">Whither HTTP?</h2>
<p>
But wait, you ask, doesn't HTTP already provide a way to communicate response statuses? Why yes, astute reader, it does. So how does the notion of indicating response status in the message body fit within the context of HTTP? Two things:
</p>
<ul><li>The official HTTP spec has 41 status codes, and there are many interpretations on how to use each one. JSend, on the other hand, defines a more constrained set of status codes, specifically related to handling JSON traffic in the context of a dynamic web UI.
</li><li>The spec is meant to be as small, constrained, and generally-applicable as possible. As such, it has to be somewhat self-contained. A common pattern for implementing JSON services is to load a <a class="missing wiki" href="/labs/jsend/wiki/JavaScript" rel="nofollow">JavaScript?</a> file which passes a JSON block into a user-specified callback. JSON-over-XHR handling in many <a class="missing wiki" href="/labs/jsend/wiki/JavaScript" rel="nofollow">JavaScript?</a> frameworks follows similar patterns. As such, the end-user (developer) never has a chance to access the HTTP response itself.
</li></ul><p>
So where does that leave us? Accounting for deficiencies in the status quo does not negate the usefulness of HTTP compliance. Therefore it is advised that server-side developers use both: provide a JSend response body, and whatever HTTP header(s) are most appropriate to the corresponding body.
</p>
<h2 id="License">License</h2>
<p>
The JSend specification (this page) is covered under a <a class="wiki" href="/labs/jsend/wiki/License">modified BSD License</a>
</p>
</div>
</div>
<script type="text/javascript">
addHeadingLinks(document.getElementById("searchable"), "Link to this section");
</script>
</div>
<script type="text/javascript">searchHighlight()</script>
<div id="altlinks"><h3>Download in other formats:</h3><ul><li class="first last"><a href="/labs/jsend/wiki/WikiStart?format=txt">Plain Text</a></li></ul></div>
</div>
<div id="footer">
<hr />
<!--
<a id="tracpowered" href="http://trac.edgewall.org/"><img src="/labs/trac_logo_mini.png" height="30" width="107"
alt="Trac Powered"/></a>
<p class="left">
Powered by <a href="/labs/jsend/about"><strong>Trac 0.10.3</strong></a><br />
By <a href="http://www.edgewall.org/">Edgewall Software</a>.
</p>
<p class="right">
Visit the Trac open source project at<br /><a href="http://trac.edgewall.org/">http://trac.edgewall.org/</a>
</p>
-->
</div>
<script src="https://ssl.google-analytics.com/urchin.js" type="text/javascript">
</script>
<script type="text/javascript">
_uacct = "UA-2585213-3";
urchinTracker();
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment