This repository has been archived by the owner on Nov 13, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3
/
index.html
309 lines (263 loc) · 9.1 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>JSON API: Convention driven API design</title>
<meta name="description" content="A talk, about JSON API.">
<meta name="author" content="Steve Klabnik">
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<link rel="stylesheet" href="css/reveal.min.css">
<link rel="stylesheet" href="css/theme/night.css" id="theme">
<!-- For syntax highlighting -->
<link rel="stylesheet" href="lib/css/zenburn.css">
<!-- If the query includes 'print-pdf', use the PDF print sheet -->
<script>
document.write( '<link rel="stylesheet" href="css/print/' + ( window.location.search.match( /print-pdf/gi ) ? 'pdf' : 'paper' ) + '.css" type="text/css" media="print">' );
</script>
<!--[if lt IE 9]>
<script src="lib/js/html5shiv.js"></script>
<![endif]-->
</head>
<body>
<div class="reveal">
<!-- Any section element inside of this container is displayed as a slide -->
<div class="slides">
<section>
<h1>JSON API</h1>
<h3>Convention driven API design</h3>
<p>
@steveklabnik
</p>
</section>
<section>
<p>The Zen of Python: explicit is better than implicit</p>
<p>Ruby on Rails: Convention over configuration</p>
</section>
<section>
<code data-trim>
GET /<br />
Host: steveklabnik.com
</code>
</section>
<section>
<code data-trim>
$ curl -I steveklabnik.com<br />
HTTP/1.1 200 OK<br />
Content-Type: text/html
</code>
</section>
<section>
<h2>Media types</h2>
<ul>
<li><code>text/plain</code></li>
<li><code>text/html</code></li>
<li><code>application/json</code></li>
<li><code>image/png</code></li>
</ul>
</section>
<section>
<h2>Zen or CoC?</h2>
<h3>Have our cake and eat it too</h3>
<p>Media types are <strong>explicit conventions</strong>.</p>
</section>
<section>
<h2>Zen or CoC?</h2>
<p>Media types are <strong>explicit</strong> because we have <code>Content-Type</code> and the related RFC.</p>
</section>
<section>
<h2>Zen or CoC?</h2>
<p>Media types are <strong>conventions</strong> because we have a shared understanding of processing rules.</p>
</section>
<section>
<h2>Common API media types</h2>
<ul>
<li><code>application/json</code></li>
</ul>
<blockquote>JavaScript Object Notation (JSON) is a lightweight, text-based, language-independent data interchange format. It was derived from the ECMAScript Programming Language Standard. JSON defines a small set of formatting rules for the portable representation of structured data.</blockquote>
</section>
<section>
<h2>Problems with JSON</h2>
<p>JSON's minimalism can only encode the vague structure of your data.</p>
<p>This has led to an explosion of bespoke, artisanal, hand-crafted APIs.</p>
</section>
<section>
<h2>Problems with JSON</h2>
<blockquote>The purpose of the Content-Type field is to describe the data contained in the body fully enough that the receiving user agent can pick an appropriate agent or mechanism to present the data to the user, or otherwise deal with the data in an appropriate manner. </blockquote>
</section>
<section>
<h2>Problems with JSON</h2>
<p>Any sufficiently advanced API contains an ad-hoc, informally specified implementation of some media type that extends JSON.</p>
</section>
<section>
<h2>Problems with JSON</h2>
<p><code>application/json</code> leads to bikeshedding. Bikeshedding leads to anger. Anger leads to hate. Hate leads to suffering.</p>
</section>
<section>
<h2>Solution:</h2>
<img src="http://imgs.xkcd.com/comics/standards.png" />
</section>
<section>
<h2>Solution:<br />JSON API</h2>
<p><a href="http://jsonapi.org">http://jsonapi.org</a></p>
</section>
<section>
<h2>JSON API</h2>
<p>JSON API assumes that you have some collection of data<br /> that you'd like to synchronize across a network boundary.</p>
<p>Its conventions allow you to build<br />a smart client that minimizes requests.</p>
</section>
<section>
<h2>JSON API</h2>
<p>It's based on real code used by real sites.<br />We use it at my employer to process payments.<br />If it's good enough for money, it's good enough for your API.</p>
<p>It's co-authored by Yehuda Katz and myself.</p>
</section>
<section>
<h2>JSON API</h2>
<p>Here's what JSON API (in the ID style) looks like:</p>
<pre><code data-trim>
{
"posts": [{
"id": "1",
"title": "Rails is Omakase",
"links": {
"author": "9",
"comments": [ "5", "12", "17", "20" ]
}
}]
}
</code></pre>
</section>
<section>
<h2>JSON API</h2>
<p>and in the URL style:</p>
<pre><code data-trim>
{
"posts": [{
"id": "1",
"title": "Rails is Omakase",
"links": {
"author": "http://example.com/people/1",
"comments": "http://example.com/comments/5,12,17,20"
}
}]
}
</code></pre>
</section>
<section>
<h2>JSON API</h2>
<p>URI Templates:</p>
<pre><code data-trim>
{
"links": {
"posts.comments": "http://example.com/posts/{posts.id}/comments"
},
"posts": [{
"id": "1",
"title": "Rails is Omakase"
}, {
"id": "2",
"title": "The Parley Letter"
}]
}
</code></pre>
</section>
<section>
<h2>JSON API</h2>
<p>Not just for <code>GET</code></p>
<pre><code data-trim>
GET /photos
HTTP/1.1 200 OK
Content-Type: application/vnd.api+json
{
"photos": [{
"id": "1",
"title": "Mustaches on a Stick"
"src": "http://example.com/images/mustache.png"
}]
}
</code></pre>
</section>
<section>
<h2>JSON API</h2>
<p>Not just for <code>GET</code></p>
<pre><code data-trim>
POST /photos
Content-Type: application/vnd.api+json
Accept: application/vnd.api+json
{
"photos": [{
"title": "Ember Hamster",
"src": "http://example.com/images/productivity.png"
}]
}
</code></pre>
</section>
<section>
<h2>JSON API</h2>
<p>Not just for <code>GET</code></p>
<pre><code data-trim>
GET /photos
HTTP/1.1 200 OK
Content-Type: application/vnd.api+json
{
"photos": [{
"id": "1",
"title": "Mustaches on a Stick"
"src": "http://example.com/images/mustache.png"
}, {
"id": "2",
"title": "Ember Hamster",
"src": "http://example.com/images/productivity.png"
}]
}
</code></pre>
</section>
<section>
<h2>JSON API</h2>
<p><a href="http://restpack-serializer-sample.herokuapp.com/">Other examples</a></p>
</section>
<section>
<h2>Conclusion</h2>
<ul>
<li>Media types are explicit conventions.</li>
<li>Conventions improve productivity by reducing bikeshedding.</li>
<li>Conventions pave the path for reusability.</li>
<li>Pick a media type that fits your application.</li>
<li>If you don't know, try JSON API.</li>
</ul>
</section>
<section>
<h1>Thanks!</h1>
<h2>http://jsonapi.org</h2>
<p>
<a href="http://twitter.com/steveklabnik">@steveklabnik</a> / <a href="mailto:[email protected]">[email protected]</a>
</p>
</section>
</div>
</div>
<script src="lib/js/head.min.js"></script>
<script src="js/reveal.min.js"></script>
<script>
// Full list of configuration options available here:
// https://github.com/hakimel/reveal.js#configuration
Reveal.initialize({
controls: true,
progress: true,
history: true,
center: true,
theme: Reveal.getQueryHash().theme, // available themes are in /css/theme
transition: Reveal.getQueryHash().transition || 'default', // default/cube/page/concave/zoom/linear/fade/none
// Optional libraries used to extend on reveal.js
dependencies: [
{ src: 'lib/js/classList.js', condition: function() { return !document.body.classList; } },
{ src: 'plugin/markdown/marked.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
{ src: 'plugin/markdown/markdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
{ src: 'plugin/highlight/highlight.js', async: true, callback: function() { hljs.initHighlightingOnLoad(); } },
{ src: 'plugin/zoom-js/zoom.js', async: true, condition: function() { return !!document.body.classList; } },
{ src: 'plugin/notes/notes.js', async: true, condition: function() { return !!document.body.classList; } }
]
});
</script>
</body>
</html>