summaryrefslogtreecommitdiffstats
path: root/docs/en/cowboy/2.0/guide/rest_flowcharts/index.html
blob: fa510cf4d5a92c1caa0dacde16248b45802a9a6d (plain) (blame)
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
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="description" content="">
    <meta name="author" content="Loïc Hoguin based on a design from (Soft10) Pol Cámara">

    <meta name="generator" content="Hugo 0.30.2" />

    <title>Nine Nines: REST flowcharts</title>

    <link href='https://fonts.googleapis.com/css?family=Open+Sans:400,700,400italic' rel='stylesheet' type='text/css'>
    <link href="/css/99s.css?r=1" rel="stylesheet">

    <link rel="shortcut icon" href="/img/ico/favicon.ico">
    <link rel="apple-touch-icon-precomposed" sizes="114x114" href="/img/ico/apple-touch-icon-114.png">
    <link rel="apple-touch-icon-precomposed" sizes="72x72" href="/img/ico/apple-touch-icon-72.png">
    <link rel="apple-touch-icon-precomposed" href="/img/ico/apple-touch-icon-57.png">

    
</head>


<body class="">
  <header id="page-head">
    <div id="topbar" class="container">
        <div class="row">
          <div class="span2">
            <h1 id="logo"><a href="/" title="99s">99s</a></h1>
          </div>
          <div class="span10">
            
            <div id="side-header">
              <nav>
                <ul>
                  <li><a title="Hear my thoughts" href="/articles">Articles</a></li>
  				  <li><a title="Watch my talks" href="/talks">Talks</a></li>
  				  <li class="active"><a title="Read the docs" href="/docs">Documentation</a></li>
  				  <li><a title="Request my services" href="/services">Consulting & Training</a></li>
                </ul>
              </nav> 
              <ul id="social">
                <li>
                  <a href="https://github.com/ninenines" title="Check my Github repositories"><img src="/img/ico_github.png" data-hover="/img/ico_github_alt.png" alt="Github"></a>
                </li>
                    <li>
						<a title="Keep in touch!" href="http://twitter.com/lhoguin"><img src="/img/ico_microblog.png" data-hover="/img/ico_microblog_alt.png"></a>
					</li>
                    <li>
						<a title="Contact me" href="mailto:[email protected]"><img src="/img/ico_mail.png" data-hover="/img/ico_mail_alt.png"></a>
					</li>
              </ul>
            </div>
          </div>
        </div>
    </div>


</header>

<div id="contents" class="two_col">
<div class="container">
<div class="row">
<div id="docs" class="span9 maincol">

<h1 class="lined-header"><span>REST flowcharts</span></h1>

<div class="paragraph"><p>This chapter will explain the REST handler state machine through
a number of different diagrams.</p></div>
<div class="paragraph"><p>There are four main paths that requests may follow. One for the
method OPTIONS; one for the methods GET and HEAD; one for the
methods PUT, POST and PATCH; and one for the method DELETE.</p></div>
<div class="paragraph"><p>All paths start with the "Start" diagram, and all paths excluding
the OPTIONS path go through the "Content negotiation" diagram
and optionally the "Conditional requests" diagram if the resource
exists.</p></div>
<div class="paragraph"><p>The red squares refer to another diagram. The light green squares
indicate a response. Other squares may be either a callback or a
question answered by Cowboy itself. Green arrows tend to indicate
the default behavior if the callback is undefined.</p></div>
<div class="sect1">
<h2 id="_start">Start</h2>
<div class="sectionbody">
<div class="paragraph"><p>All requests start from here.</p></div>
<div class="imageblock">
<div class="content">
<img src="../rest_start.png" alt="REST starting flowchart" />
</div>
</div>
<div class="paragraph"><p>A series of callbacks are called in succession to perform
a general checkup of the service, the request line and
request headers.</p></div>
<div class="paragraph"><p>The request body, if any, is not expected to have been
received for any of these steps. It is only processed
at the end of the "PUT, POST and PATCH methods" diagram,
when all conditions have been met.</p></div>
<div class="paragraph"><p>The <code>known_methods</code> and <code>allowed_methods</code> callbacks
return a list of methods. Cowboy then checks if the request
method is in the list, and stops otherwise.</p></div>
<div class="paragraph"><p>The <code>is_authorized</code> callback may be used to check that
access to the resource is authorized. Authentication
may also be performed as needed. When authorization is
denied, the return value from the callback must include
a challenge applicable to the requested resource, which
will be sent back to the client in the www-authenticate
header.</p></div>
<div class="paragraph"><p>This diagram is immediately followed by either the
"OPTIONS method" diagram when the request method is
OPTIONS, or the "Content negotiation" diagram otherwise.</p></div>
</div>
</div>
<div class="sect1">
<h2 id="_options_method">OPTIONS method</h2>
<div class="sectionbody">
<div class="paragraph"><p>This diagram only applies to OPTIONS requests.</p></div>
<div class="imageblock">
<div class="content">
<img src="../rest_options.png" alt="REST OPTIONS method flowchart" />
</div>
</div>
<div class="paragraph"><p>The <code>options</code> callback may be used to add information
about the resource, such as media types or languages
provided; allowed methods; any extra information. A
response body may also be set, although clients should
not be expected to read it.</p></div>
<div class="paragraph"><p>If the <code>options</code> callback is not defined, Cowboy will
send a response containing the list of allowed methods
by default.</p></div>
</div>
</div>
<div class="sect1">
<h2 id="_content_negotiation">Content negotiation</h2>
<div class="sectionbody">
<div class="paragraph"><p>This diagram applies to all request methods other than
OPTIONS. It is executed right after the "Start" diagram
is completed.</p></div>
<div class="imageblock">
<div class="content">
<img src="../rest_conneg.png" alt="REST content negotiation flowchart" />
</div>
</div>
<div class="paragraph"><p>The purpose of these steps is to determine an appropriate
representation to be sent back to the client.</p></div>
<div class="paragraph"><p>The request may contain any of the accept header; the
accept-language header; or the accept-charset header.
When present, Cowboy will parse the headers and then
call the corresponding callback to obtain the list
of provided content-type, language or charset for this
resource. It then automatically select the best match
based on the request.</p></div>
<div class="paragraph"><p>If a callback is not defined, Cowboy will select the
content-type, language or charset that the client
prefers.</p></div>
<div class="paragraph"><p>The <code>content_types_provided</code> also returns the name of
a callback for every content-type it accepts. This
callback will only be called at the end of the
"GET and HEAD methods" diagram, when all conditions
have been met.</p></div>
<div class="paragraph"><p>The selected content-type, language and charset are
saved as meta values in the Req object. You <strong>should</strong>
use the appropriate representation if you set a
response body manually (alongside an error code,
for example).</p></div>
<div class="paragraph"><p>This diagram is immediately followed by
the "GET and HEAD methods" diagram,
the "PUT, POST and PATCH methods" diagram,
or the "DELETE method" diagram, depending on the
method.</p></div>
</div>
</div>
<div class="sect1">
<h2 id="_get_and_head_methods">GET and HEAD methods</h2>
<div class="sectionbody">
<div class="paragraph"><p>This diagram only applies to GET and HEAD requests.</p></div>
<div class="paragraph"><p>For a description of the <code>cond</code> step, please see
the "Conditional requests" diagram.</p></div>
<div class="imageblock">
<div class="content">
<img src="../rest_get_head.png" alt="REST GET/HEAD methods flowchart" />
</div>
</div>
<div class="paragraph"><p>When the resource exists, and the conditional steps
succeed, the resource can be retrieved.</p></div>
<div class="paragraph"><p>Cowboy prepares the response by first retrieving
metadata about the representation, then by calling
the <code>ProvideResource</code> callback. This is the callback
you defined for each content-types you returned from
<code>content_types_provided</code>. This callback returns the body
that will be sent back to the client, or a fun if the
body must be streamed.</p></div>
<div class="paragraph"><p>When the resource does not exist, Cowboy will figure out
whether the resource existed previously, and if so whether
it was moved elsewhere in order to redirect the client to
the new URI.</p></div>
<div class="paragraph"><p>The <code>moved_permanently</code> and <code>moved_temporarily</code> callbacks
must return the new location of the resource if it was in
fact moved.</p></div>
</div>
</div>
<div class="sect1">
<h2 id="_put_post_and_patch_methods">PUT, POST and PATCH methods</h2>
<div class="sectionbody">
<div class="paragraph"><p>This diagram only applies to PUT, POST and PATCH requests.</p></div>
<div class="paragraph"><p>For a description of the <code>cond</code> step, please see
the "Conditional requests" diagram.</p></div>
<div class="imageblock">
<div class="content">
<img src="../rest_put_post_patch.png" alt="REST PUT/POST/PATCH methods flowchart" />
</div>
</div>
<div class="paragraph"><p>When the resource exists, first the conditional steps
are executed. When that succeeds, and the method is PUT,
Cowboy will call the <code>is_conflict</code> callback. This function
can be used to prevent potential race conditions, by locking
the resource for example.</p></div>
<div class="paragraph"><p>Then all three methods reach the <code>content_types_accepted</code>
step that we will describe in a few paragraphs.</p></div>
<div class="paragraph"><p>When the resource does not exist, and the method is PUT,
Cowboy will check for conflicts and then move on to the
<code>content_types_accepted</code> step. For other methods, Cowboy
will figure out whether the resource existed previously,
and if so whether it was moved elsewhere. If the resource
is truly non-existent, the method is POST and the call
for <code>allow_missing_post</code> returns <code>true</code>, then Cowboy will
move on to the <code>content_types_accepted</code> step. Otherwise
the request processing ends there.</p></div>
<div class="paragraph"><p>The <code>moved_permanently</code> and <code>moved_temporarily</code> callbacks
must return the new location of the resource if it was in
fact moved.</p></div>
<div class="paragraph"><p>The <code>content_types_accepted</code> returns a list of
content-types it accepts, but also the name of a callback
for each of them. Cowboy will select the appropriate
callback for processing the request body and call it.</p></div>
<div class="paragraph"><p>This callback may return one of three different return
values.</p></div>
<div class="paragraph"><p>If an error occurred while processing the request body,
it must return <code>false</code> and Cowboy will send an
appropriate error response.</p></div>
<div class="paragraph"><p>If the method is POST, then you may return <code>true</code> with
an URI of where the resource has been created. This is
especially useful for writing handlers for collections.</p></div>
<div class="paragraph"><p>Otherwise, return <code>true</code> to indicate success. Cowboy
will select the appropriate response to be sent depending
on whether a resource has been created, rather than
modified, and on the availability of a location header
or a body in the response.</p></div>
</div>
</div>
<div class="sect1">
<h2 id="_delete_method">DELETE method</h2>
<div class="sectionbody">
<div class="paragraph"><p>This diagram only applies to DELETE requests.</p></div>
<div class="paragraph"><p>For a description of the <code>cond</code> step, please see
the "Conditional requests" diagram.</p></div>
<div class="imageblock">
<div class="content">
<img src="../rest_delete.png" alt="REST DELETE method flowchart" />
</div>
</div>
<div class="paragraph"><p>When the resource exists, and the conditional steps
succeed, the resource can be deleted.</p></div>
<div class="paragraph"><p>Deleting the resource is a two steps process. First
the callback <code>delete_resource</code> is executed. Use this
callback to delete the resource.</p></div>
<div class="paragraph"><p>Because the resource may be cached, you must also
delete all cached representations of this resource
in the system. This operation may take a while though,
so you may return before it finished.</p></div>
<div class="paragraph"><p>Cowboy will then call the <code>delete_completed</code> callback.
If you know that the resource has been completely
deleted from your system, including from caches, then
you can return <code>true</code>. If any doubts persist, return
<code>false</code>. Cowboy will assume <code>true</code> by default.</p></div>
<div class="paragraph"><p>To finish, Cowboy checks if you set a response body,
and depending on that, sends the appropriate response.</p></div>
<div class="paragraph"><p>When the resource does not exist, Cowboy will figure out
whether the resource existed previously, and if so whether
it was moved elsewhere in order to redirect the client to
the new URI.</p></div>
<div class="paragraph"><p>The <code>moved_permanently</code> and <code>moved_temporarily</code> callbacks
must return the new location of the resource if it was in
fact moved.</p></div>
</div>
</div>
<div class="sect1">
<h2 id="_conditional_requests">Conditional requests</h2>
<div class="sectionbody">
<div class="paragraph"><p>This diagram applies to all request methods other than
OPTIONS. It is executed right after the <code>resource_exists</code>
callback, when the resource exists.</p></div>
<div class="imageblock">
<div class="content">
<img src="../rest_cond.png" alt="REST conditional requests flowchart" />
</div>
</div>
<div class="paragraph"><p>A request becomes conditional when it includes either of
the if-match header; the if-unmodified-since header; the
if-none-match header; or the if-modified-since header.</p></div>
<div class="paragraph"><p>If the condition fails, the request ends immediately
without any retrieval or modification of the resource.</p></div>
<div class="paragraph"><p>The <code>generate_etag</code> and <code>last_modified</code> are called as
needed. Cowboy will only call them once and then cache
the results for subsequent use.</p></div>
</div>
</div>



	
		
		
		
		
		

		<nav style="margin:1em 0">
			
				<a style="float:left" href="https://ninenines.eu/docs/en/cowboy/2.0/guide/rest_handlers/">
					REST handlers
				</a>
			

			
				<a style="float:right" href="https://ninenines.eu/docs/en/cowboy/2.0/guide/resource_design/">
					Designing a resource handler
				</a>
			
		</nav>
	



</div>

<div class="span3 sidecol">


<h3>
	Cowboy
	2.0
	
	User Guide
</h3>

<ul>
	
		<li><a href="/docs/en/cowboy/2.0/guide">User Guide</a></li>
	
	
		<li><a href="/docs/en/cowboy/2.0/manual">Function Reference</a></li>
	
	
</ul>

<h4 id="docs-nav">Navigation</h4>

<h4>Version select</h4>
<ul>
	
	
	
		<li><a href="/docs/en/cowboy/2.1/guide">2.1</a></li>
	
		<li><a href="/docs/en/cowboy/2.0/guide">2.0</a></li>
	
		<li><a href="/docs/en/cowboy/1.0/guide">1.0</a></li>
	
</ul>

</div>
</div>
</div>
</div>

      <footer>
        <div class="container">
          <div class="row">
            <div class="span6">
              <p id="scroll-top"><a href="#">↑ Scroll to top</a></p>
              <nav>
                <ul>
                  <li><a href="mailto:[email protected]" title="Contact us">Contact us</a></li><li><a href="https://github.com/ninenines/ninenines.github.io" title="Github repository">Contribute to this site</a></li>
                </ul>
              </nav>
            </div>
            <div class="span6 credits">
               <p><img src="/img/footer_logo.png"></p>
               <p>Copyright &copy; Loïc Hoguin 2012-2016</p>
            </div>
          </div>
        </div>
      </footer>

    
    <script src="/js/custom.js"></script>
  </body>
</html>