-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.html
658 lines (601 loc) · 28.3 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
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>RESTful Web APIs</title>
<meta name="description" content="RESTful Web APIs and the Hypermedia Constraint">
<meta name="author" content="Alex Moore-Niemi">
<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, minimal-ui">
<link rel="stylesheet" href="css/reveal.css">
<link rel="stylesheet" href="css/theme/white.css" id="theme">
<!-- Code syntax highlighting -->
<link rel="stylesheet" href="lib/css/zenburn.css">
<!-- Printing and PDF exports -->
<script>
var link = document.createElement( 'link' );
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = window.location.search.match( /print-pdf/gi ) ? 'css/print/pdf.css' : 'css/print/paper.css';
document.getElementsByTagName( 'head' )[0].appendChild( link );
</script>
<!--[if lt IE 9]>
<script src="lib/js/html5shiv.js"></script>
<![endif]-->
<style>
.bubble
{
position: relative;
width: 100%;
height: 10%;
padding: 20px !important;
background: #F0F0F5;
-webkit-border-radius: 18px !important;
-moz-border-radius: 18px !important;
border-radius: 18px !important;
border: #7F7F7F solid 4px !important;
}
.bubble:after
{
content: '';
position: absolute;
border-style: solid;
border-width: 15px 0 15px 35px;
border-color: transparent #F0F0F5;
display: block;
width: 0;
z-index: 1;
right: -35px;
top: 45px;
}
.bubble:before
{
content: '';
position: absolute;
border-style: solid;
border-width: 18px 0 18px 38px;
border-color: transparent #7F7F7F;
display: block;
width: 0;
z-index: 0;
right: -42px;
top: 42px;
}
</style>
</head>
<body>
<div class="reveal">
<!-- Any section element inside of this container is displayed as a slide -->
<div class="slides">
<section data-background="big-sloth.jpg">
<h1 style="background-color:rgba(255, 255, 0, 0.5);">RESTful Web APIs</h1>
<h3 style="background-color:rgba(255, 0, 102, 0.5);">& the hypermedia constraint</h3>
<p style="background-color:rgba(0, 255, 255, 0.5);">
<a href="https://twitter.com/feminstwerewolf" style="color:black;">Alex Moore-Niemi</a>
</p>
</section>
<section>
<section>
<h2>What's the intent of this presentation?</h2>
<p>
To get you to build RESTful web APIs, and to use the hypermedia constraint as a tool for doing that.
</p>
</section>
<section>
<p>How do you get someone to use something?</p>
<p class="fragment"><s>force</s></p>
<ol>
<li class="fragment">inspire them to <i>want</i> to use it</li>
<li class="fragment">show them <i>how</i> to use it</li>
</ol>
</section>
</section>
<section>
<section>
<h2>Why build RESTful Web APIs?</h2>
<p class="fragment">Constraints restrict complexity.</p>
<p class="fragment">Flexibility for growth.</p>
<p class="fragment">Ubiquitous support.</p>
</section>
<section>
<h2>REST has 4 constraints</h2>
<ul>
<li>identification of resources</li>
<li>manipulation of resources through representations</li>
<li>self-descriptive messages</li>
<li>hypermedia as the engine of application state</li>
</ul>
</section>
<section>
<h2>Is REST new?</h2>
<p class="bubble"><i>*muttering* Just seems like hype to me!</i></p>
<h2 class="fragment">No.</h2>
<p class="fragment" align="left">REST (<a href="https://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm">Representational State Transfer</a>) is merely an academic codification of the architectural constraints that describe the Web.</p>
</section>
</section>
<section>
<h2>What <i>is</i> the Web?</h2>
<p>
HTTP, URLs, and HTML.
</p>
<p class="fragment bubble"><i>Pssst.</i> What about Javascript?</p>
<p class="fragment" align="left">It satisfies one of the <i>optional</i> constraints in REST: "Mobile Code On Demand".</p>
</section>
<section data-background="raptor_blur.jpg">
<p style="color:white;">But like, what <i>IS</i> the web???</p>
<p style="color:white;" class="fragment">The web is a distributed computing system.</p>
<p style="color:white;" class="fragment">What do all useful computational systems need to do?</p>
<p style="color:white;" class="fragment">Manipulate <i>state</i>.</p>
</section>
<section id="state-kinds">
<p>State on the Web is of two types:</p>
<ol>
<li>Resource state</li>
<li>Application state</li>
</ol>
<p>How do we make state changes?</p>
<p class="fragment">Representations!</p>
<p class="fragment">(That's why it's called Representational State Transfer. :))</p>
<p class="fragment"><a href="#/transition-kinds">How do we represent state transitions on the web?</a></p>
</section>
</section>
<section>
<section>
<p>Working RESTfully means leveraging the Web as a core technology and organizing principle.</p>
<p>
How do we generally approach writing programs?
</p>
<p class="fragment">We model what we think needs to happen.</p>
<p class="fragment">We check for libraries that support our use case.</p>
<p class="fragment">We re-model our first pass given existing libraries.</p>
<p class="fragment">We write our program in the context of a dependency graph.</p>
</section>
<section>
<p>If we approach the "Web" as libraries we can use, what do we get out of the box?</p>
<h2 class="fragment" style="color: #FF0066;">Protocol semantics.</h2>
<h2 class="fragment" style="color: #FF99C2;">Domain semantics.</h2>
<h2 class="fragment" style="color: #FFCCE0;">Application semantics.</h2>
</section>
</section>
<section>
<section>
<p>What are protocol semantics anyway?</p>
<blockquote class="fragment">"the set of rules regarding how to fashion valid requests and responses using one or more message protocols"</blockquote>
</section>
<section>
<p class="bubble">Yeah, yeah yeah... I've seen POST, PUT, DELETE, etc...</p>
<p class="fragment">HTTP alone has a lot more semantics than you might think.</p>
</section>
<section>
<ul>
<li><a href="https://tools.ietf.org/html/rfc7230">RFC 7230</a>, HTTP/1.1: Message Syntax and Routing</li>
<li><a href="https://tools.ietf.org/html/rfc7231">RFC 7231</a>, HTTP/1.1: Semantics and Content</li>
<li><a href="https://tools.ietf.org/html/rfc7232">RFC 7232</a>, HTTP/1.1: Conditional Requests</li>
<li><a href="https://tools.ietf.org/html/rfc7233">RFC 7233</a>, HTTP/1.1: Range Requests</li>
<li><a href="https://tools.ietf.org/html/rfc7234">RFC 7234</a>, HTTP/1.1: Caching</li>
<li><a href="https://tools.ietf.org/html/rfc7235">RFC 7235</a>, HTTP/1.1: Authentication</li>
</ul>
<p>HTTP/2 was published as <a href="https://tools.ietf.org/html/rfc7540">RFC 7540</a> in May 2015.</p>
</section>
<section>
<p class="bubble">Meh. Why not just overload POST with everything you need?</p>
<p class="fragment" align="left">When you use POST with overloaded semantics, you're limiting yourself to thinking in function calls.</p>
<p class="fragment" align="left">Your alternative is <a href="http://www.sapphiresteel.com/Tutorials/sapphire-ruby-in-steel-tutorials/Programming/Ruby-The-Smalltalk-Way-1.html">message passing</a>. Does the Web offer that?</p>
<h2 class="fragment" align="left">Yes.</h2>
<p class="fragment" align="left">One of the Fielding constraints of REST is "self-describing messages", because the web <b>requires</b> a message passing style for its distributed model.</p>
</section>
<section>
<p align="left" class="bubble">What can message passing give us that function calling can't?</p>
<p class="fragment" align="left">Formally, they're equivalent. But if you expose functions, you've exposed method signatures, which couple your client's implementation to yours directly.</p>
<p class="fragment" align="left">Instead we want to think declaratively: send a message of the desired state change, don't ask for a specific function to handle it.</p>
</section>
<section>
<blockquote>The key in making great and growable systems is much more to design how its modules communicate rather than what their internal properties and behaviors should be. Think of the internet - to live, it (a) has to allow many different kinds of ideas and realizations that are beyond any single standard and (b) to allow varying degrees of safe interoperability between these ideas. </blockquote>
</section>
<section>
<blockquote>If you focus on just messaging - and realize that a good metasystem can late bind the various 2nd level architectures used in objects - then much of the language-, UI-, and OS based discussions on this thread are really quite moot.</blockquote>
<p>Alan Kay (inventor of Smalltalk), <a href="http://c2.com/cgi/wiki?AlanKayOnMessaging">on messaging</a></p>
</section>
<section>
<p align="left">For instance, if you want to create something and format your POST request wrong, <span class="fragment" align="left">the server could inspect your malformed message and reply with a response explaining <i>how</i> to actually create the new resource you were addressing.</span></p>
<p class="fragment" align="left"> If you're POST'ing essentially to just an undefined function (RPC-style) the server can't do any better than say "this doesn't exist in my namespace. :c"</p>
</section>
<section>
<p>Our standard error response:</p>
<pre><code>{
key: "system_error"
message: "An unexpected error has occurred. Please contact support if the problem persists."
}
</pre></code>
<p>Collection+JSON write template:</p>
<pre><code>"template" : {
"data" : [
{"name" : "full-name", "prompt" : "Full Name"},
{"name" : "email", "prompt" : "Email"},
{"name" : "blog", "prompt" : "Blog"},
{"name" : "avatar", "prompt" : "Avatar"}
]
}
</pre></code>
</section>
</section>
<section>
<section>
<p align="left">Protocol semantics help define the control flow of our application, but they would be a pretty weak application on their own.</p>
<table>
<tr><td>POST</td><td>Create</td></tr>
<tr><td>GET</td><td>Read</td></tr>
<tr><td>PUT</td><td>Update</td></tr>
<tr><td>PATCH</td><td></td></tr>
<tr><td>DELETE</td><td>Delete</td></tr>
</table>
<p align="left" class="fragment">If we need more than CRUD, we need our own application semantics. So protocol semantics at bottom, application semantics at top...</p>
</section>
<section>
<p align="left">Between "<span style="color:#339966;">the HTTP request necessary to trigger a state transition</span>" and "<span style="color:#3366CC;">the purpose of the state transition</span>"...</p>
<p class="fragment" align="right">How do we fill the gap?</p>
<p class="fragment" id="fill_the_gap" data-state="fill_the_gap"></p>
<p><canvas id="semantics_pyramid" width="600" height="600"></canvas></p>
</section>
</section>
<!-- talk about Gopher here? -->
<section>
<h2>HTML</h2>
<p align="left">Hyper Text Markup Language is the original hypermedia type.</p>
<div id="factors" style="width:20%;padding:10px;float:right;clear:both;">
<table class="hfactors">
<thead>
<tr>
<th colspan="5"><a href="http://amundsen.com/hypermedia/hfactor/" title="Hypermedia Factors" class="hfactor-link">Hypermedia Factors</a></th>
</tr>
</thead>
<tbody>
<tr>
<td></td>
<td></td>
<td class="border cd"><a href="/hypermedia/hfactor/#cl" title="Control Data for Links">CL</a></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td class="border">CR</td>
<td class="border cd"><a href="/hypermedia/hfactor/#cu" title="Control Data for Updates">CU</a></td>
<td class="border cd"><a href="/hypermedia/hfactor/#cm" title="Control Data for Interface Methods">CM</a></td>
<td></td>
</tr>
<tr>
<td class="border ld"><a href="/hypermedia/hfactor/#le" title="Embedded Links">LE</a></td>
<td class="border ld"><a href="/hypermedia/hfactor/#lo" title="Outbound Links">LO</a></td>
<td class="border ld"><a href="/hypermedia/hfactor/#lt" title="Templated Links">LT</a></td>
<td class="border ld"><a href="/hypermedia/hfactor/#ln" title="Non-Idempotent Update Links">LN</a></td>
<td class="border">LI</td>
</tr>
</tbody>
</table>
</div>
<p align="left">Its <b>protocol semantics</b> are limited: <font color="red">PUT and DELETE from HTTP are not supported</font>.</p>
<p align="left">Its <b>domain semantics</b> are specifically about sharing <a href="http://www.w3.org/TR/html5/">a network of human readable documents</a>, which is a very popular and very flexible domain.</p>
<p align="left">If your application matches that domain 1:1, you're all set: HTML has you covered. (Consider <a href="https://www.wikipedia.org/">Wikipedia</a>.)</p>
</section>
<section data-background="http://www.icxm.net/team/uploads/Misc/1.png">
<pre><code><a href="" rel="">This is where we will start our API.</a></code></pre>
</section>
<section>
<section>
<h2>Hypermedia</h2>
<blockquote>
"a way for the server to tell the client what HTTP requests the client might want to make in the future"
</blockquote>
</section>
<section id="transition-kinds">
<p align="left"><a href="http://amundsen.com/hypermedia/hfactor/">H-Factors</a> are the categories of <b>state transitions</b> that hypermedia can help the client and server format as representations (messages).</p>
<pre><code data-trim contenteditable>
<img src="http://www.example.org/images/logo" title="company logo" />
<a href="http://www.example.org/search" title="view search page">Search</a>
<form method="get">
<label>Search term:</label>
<input name="query" type="text" value="" />
<input type="submit" />
</form>
<form method="post" action="http://www.example.org/my-keywords"/>
<label>Keywords:</label>
<input name="keywords" type="text" value="" />
<input type="submit" />
</form>
</code></pre>
<a href="#/state-kinds">What kinds of state do we have on the web?</a>
</section>
</section>
<section>
<section data-background="baby-sloth.jpg">
<p style="background-color:rgba(0, 0, 0, 0.7); color:white;">So how do we <a href="http://www.slideshare.net/rnewton/api-design-methodology-mike-amundsen-director-of-api-architecture-api-academy-apidays-sydney">design a RESTful API</a>? (In brief.)</p>
</section>
<section>
<ol><li><p><span><b>Semantic descriptors</b>: list all info a client might have as input/output</span></p></li>
<li><p><span><b>Link relations</b>: Draw a state diagram</span></p></li>
<li><p><span><b>Check against existing profiles</b>: can you leverage any?</span></p></li>
<li><p><span><b>Choose a media type</b></span></p></li>
<li><p><span><b>Write your profile of your application semantics</b></span></p><p><span><small>The more you found in 3 and 4, the less you need to do in 5.</small></span></p></li>
<li style="color:grey;"><p><b><span style="color:grey;">Code!!</b></span></p></li>
<li style="color:grey;"><p><b><span style="color:grey;">Publish the "billboard URL"</b></span></p></li>
</ol>
<small><p><a href="https://books.google.com/books?id=wWnGAAAAQBAJ&lpg=PA146&ots=FfcpzHY94a&dq=%22semantic%20descriptors%22%20amundsen&pg=PA158#v=onepage&q&f=false">7 Step Design Procedure</a> from <a href="http://www.amazon.com/RESTful-Web-APIs-Leonard-Richardson/dp/1449358063">RESTful Web APIs</a> by Leonard Richardson, Mike Amundsen, Sam Ruby</p></small>
</section>
<section>
<p align="left">ZipErrands API</p>
<p align="left"><b>Use case</b>: As a Zipcar member, I want to find the nearest car available, so that I can use it to run an errand that will take under an hour.</p>
</section>
<section>
<p align="left"><b>Input</b>: current location of user.</p>
<p align="left"><b>Output</b>: cars (must have distance to, features, picture of), car keys (allows device to unlock car), reservation invoice (billed amount).</p>
<p align="left"><b>Semantic descriptors</b>: current_location, distance_to, features, picture_of, car_keys, reservation_invoice</p>
</section>
<section>
<p align="left"><b>Link relations</b>: search, car, prev/next, back, claim</p>
<img src="ZipcarErrandAPI.png">
</section>
<section>
<p align="left"><b>Reconcile names</b>:</p>
<ul>
<li>current_location, distance_to: <a href="https://schema.org/GeoCoordinates">GeoCoordinates</a></li>
<li>reservation_invoice: <a href="https://schema.org/Invoice">Invoice</a></li>
<li>claim: <a href="https://schema.org/RentalCarReservation">RentalCarReservation</a></li>
<li>car: <a href="http://sdo-property-value-and-cars.appspot.com/Car">Car</a></li>
<li>cars: <a href="https://schema.org/SearchResultsPage">SearchResultsPage</a></li>
</ul>
<p class="fragment" align="right"><i>Why</i> reconcile names?</p>
<p class="fragment" align="left">Search engines like Google have a vested interest in being able to parse content on the web semantically. Ever received <a href="https://developers.google.com/gmail/markup/">an email that highlighted your upcoming flight</a>?</p>
</section>
<section>
<p>That's the power of using <a href="http://schema.org/">Schema.org</a> markup.</p>
<img src="carousel-inbox.png">
</section>
</section>
<section>
<section>
<p>What do we need out of a media type?</p>
<p class="fragment" align="left">A way for the client to figure out: <span style="color:#7070DB;" class="fragment">what kind of requests can I make<span>, <span style="color:#5A5AAF;" class="fragment">how do I make them,</span><span style="color:#363669;" class="fragment"> and <i>why</i> would I want to make them?</span></p>
<h2 class="fragment">worst case: Protocol Semantics</h2>
<h2 class="fragment">best case: Application Semantics</h2>
</section>
<section>
<pre><code>[
{
"account_billing_info_id": 5639575,
"account_id": 123456789,
"last_four": "1111",
"credit_card_type": "vi",
"account_holder_name": "Suzanne Job",
"primary": true,
"expiration_month": "02",
"expiration_year": "2019",
"address_line_one": "35 Thomson place,",
"address_line_two": "Apt No-105",
"mumciplaity": "boston",
"region": "Massachusetts",
"country": "US"
}
]</code></pre>
<p class="fragment" align="left">The media type most devs are familiar with is <a href="http://json.org/">JSON</a>, but it is <b>not</b> a <i>hyper</i>media format.</p>
<p class="fragment" align="left">What could a hypermedia format give us out of the box that a vanilla data structure like JSON can't?</p>
</section>
<section>
<p>As a client, how do I interpret <i>x</i>?</p>
<pre><code><script type="application/ld+json">
{
"@context": "http://schema.org",
"@type": "Person",
"address": {
"@type": "PostalAddress",
"addressLocality": "Seattle",
"addressRegion": "WA",
"postalCode": "98052",
"streetAddress": "20341 Whitworth Institute 405 N. Whitworth"
},
"colleague": [
"http://www.xyz.edu/students/alicejones.html",
"http://www.xyz.edu/students/bobsmith.html"
],
"email": "mailto:[email protected]",
"image": "janedoe.jpg",
"jobTitle": "Professor",
"name": "Jane Doe",
"telephone": "(425) 123-4567",
"url": "http://www.janedoe.com"
}
</script></code></pre>
</section>
<section>
<p>As a client, how do I make a request to find <i>x</i>?</p>
<pre><code>"queries" : [
{
"rel" : "search", "href" : "http://example.org/friends/search",
"prompt" : "Search",
"data" : [
{"name" : "search", "value" : ""}
]
}
],</pre></code>
<pre><code data-trim contenteditable>
<form method="get">
<label>Search term:</label>
<input name="query" type="text" value="" />
<input type="submit" />
</form>
</code></pre>
</section>
<section>
<p>As a client, how do I make a request to find <i>ys related to x</i>?</p>
<pre><code>HTTP/1.1 200 OK
Content-Type: application/vnd.api+json
{
"data": [{
"type": "articles",
"id": "1",
"attributes": {
"title": "JSON API paints my bikeshed!",
"body": "The shortest article. Ever."
},
"relationships": {
"author": {
"data": {"id": 42, "type": "people"}
}
}
}],
"included": [
{
"type": "people",
"id": 42,
"attributes": {
"name": "John"
}
}
]
}</code></pre>
<pre><code data-trim contenteditable>
HTTP/1.1 200 OK
Content-Type: application/atom+xml
<link href="http://www.example.org/data/q1w2e3r4" rel="related" hreflang="en" />
</code></pre>
</section>
<section>
<p>When we give a uniform (standardized) interface to the client, we don't need as many clients.</p>
</section>
</section>
<section>
<section>
<p>Obligatory <a href="https://developers.google.com/gmail/markup/reference/rental-car">RentalCarReservation</a> example.</p>
<pre><code><script type="application/ld+json">
{
"@context": "http://schema.org",
"@type": "RentalCarReservation",
"reservationId": "546323",
"reservationStatus": "http://schema.org/ReservationConfirmed",
"underName": {
"@type": "Person",
"name": "John Smith"
},
"reservationFor": {
"@type": "Car",
"name": "Economy Class Car",
"model": "Civic",
"brand": {
"@type": "Brand",
"name": "Honda"
},
"operatingCompany": {
"@type": "Organization",
"name": "Hertz"
}
},
"pickupLocation": {
"@type": "Place",
"name": "Hertz San Diego Airport",
"address": {
"@type": "PostalAddress",
"streetAddress": "1500 Orange Avenue",
"addressLocality": "San Diego",
"addressRegion": "CA",
"postalCode": "94043",
"addressCountry": "US"
}
},
"pickupTime": "2017-08-05T16:00:00-07:00",
"dropoffLocation": {
"@type": "Place",
"name": "Hertz LAX",
"address": {
"@type": "PostalAddress",
"streetAddress": "1234 First Street",
"addressLocality": "Los Angeles",
"addressRegion": "CA",
"postalCode": "94043",
"addressCountry": "US"
}
},
"dropoffTime": "2017-08-06T20:00:00-07:00"
}
</script></code></pre>
</section>
<section>
<a href="http://www.phonedog.com/2014/05/26/google-search-app-can-now-remind-you-of-rental-car-reservation-info"><img style="border:none; box-shadow:none;" height="70%" width="70%" src="android_rental.png"></a>
</section>
</section>
<section>
<blockquote>
"The purpose of an API is to separate the client from the implementation: the client should know nothing about the implementation other than information given in the API, and the implementation should not take properties of any particular client into account. APIs enable us to separately develop code for various purposes, then reuse it widely."
</blockquote>
<p>Sedgewick's <a href="http://www.amazon.com/Algorithms-4th-Edition-Robert-Sedgewick/dp/032157351X">Algorithms</a></p>
</section>
<section>
<h2>tl;dr</h2>
<ul>
<li class="fragment">The Web is a distributed computing system that relies on message passing.</li>
<li class="fragment"><a href="http://restful-api-design.readthedocs.org/en/latest/resources.html">Resources</a> have unique, addressable identifiers.</li>
<li class="fragment">To modify the state of a resource, you send <a href="http://restful-api-design.readthedocs.org/en/latest/resources.html#representations">representations</a>. (Messages.)</li>
<li class="fragment">These representations should be self-describing, <span class="fragment">so that the client never needs out-of-band information to make its next request.</span></li>
<li class="fragment">Work from the state transitions, <b>not</b> from the resources underneath. <span class="fragment">Design from representations of state change, <b>not</b> from the object whose state will change. <span class="fragment"><b>Work from the messages, not from the objects.</b></span></li>
</ul>
</section>
<section data-background="bunch-sloths.jpg">
<p style="background-color:rgba(0, 0, 0, 0.7); color:white;">Leverage the work of your community, and be <b>proud</b> of contributing to that community.</p>
</section>
</div>
</div>
<script src="lib/js/head.min.js"></script>
<script src="js/reveal.js"></script>
<script>
// Full list of configuration options available at:
// https://github.com/hakimel/reveal.js#configuration
Reveal.initialize({
slideNumber: true,
controls: true,
progress: true,
history: true,
center: true,
transition: 'slide', // none/fade/slide/convex/concave/zoom
// Optional reveal.js plugins
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, condition: function() { return !!document.querySelector( 'pre code' ); }, callback: function() { hljs.initHighlightingOnLoad(); } },
{ src: 'plugin/zoom-js/zoom.js', async: true },
{ src: 'plugin/notes/notes.js', async: true }
]
});
var context = document.getElementById("semantics_pyramid").getContext("2d");
var width = 400; // Triangle Width
var height = 400; // Triangle Height
var padding = 20;
// Draw a path
context.beginPath();
context.moveTo(padding + width/2, padding); // Top Corner
context.lineTo(padding + width, height + padding); // Bottom Right
context.lineTo(padding, height + padding); // Bottom Left
context.closePath();
// Fill the path
context.fillStyle = "#B2E6FF";
context.fill();
// Add a horizon reflection with a gradient to transparent
gradient = context.createLinearGradient(0,padding,0,padding+height);
gradient.addColorStop(0.5, "transparent");
gradient.addColorStop(0.5, "#B2E6FF");
gradient.addColorStop(1, "#80CC99");
// Fill the path
context.fillStyle = gradient;
context.fill();
context.font = "30px Arial";
context.fillStyle = "black";
context.fillText("Application Semantics",width/1.9,height/6);
context.fillText("Protocol Semantics",width/1.5,height);
Reveal.addEventListener( 'fragmentshown', function( event ) {
if(event.fragment.id == "fill_the_gap"){
context.fillText("Hypermedia!",width/1.5,height/1.7);
}
});
</script>
</body>
</html>