REST API's: Easier Than You Imagined
-
Upload
adam-tuttle -
Category
Technology
-
view
1.648 -
download
1
description
Transcript of REST API's: Easier Than You Imagined
![Page 1: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/1.jpg)
REST API’s:Easier Than You Imagined
@AdamTuttleFusionGrokker.com
You are here
![Page 2: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/2.jpg)
Agenda
• REST 101
• Creating REST APIs with ColdFusion*
• Adding an API to an existing app
• Best Practices, Patterns, Anti-patterns
![Page 3: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/3.jpg)
Agenda
• REST 101
• Creating REST APIs with ColdFusion*
• Adding an API to an existing app
• Best Practices, Patterns, Anti-patterns
*Using Taffy
![Page 4: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/4.jpg)
![Page 5: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/5.jpg)
I’m @AdamTuttle
![Page 6: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/6.jpg)
That’s Me!
![Page 7: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/7.jpg)
I make stuff
![Page 8: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/8.jpg)
• Created May 2010
• #6 most watched ColdFusion project on GitHub
• 8+ people contributing
• Syntax doesn’t suck
I made Taffy
![Page 9: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/9.jpg)
Who Uses Taffy?
![Page 10: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/10.jpg)
REST 101
![Page 11: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/11.jpg)
What is REST?
![Page 12: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/12.jpg)
What is REST?
![Page 13: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/13.jpg)
Request ResponseGET http://...HeadersRequest data
200 OKHeadersResponse data
![Page 14: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/14.jpg)
![Page 15: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/15.jpg)
<form action=”http://...” method=”POST”>
</form>
![Page 16: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/16.jpg)
VocabularyVerb
Noun
Data Format (“Mime Type”)
Data
![Page 17: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/17.jpg)
HTTP VerbsGET Read
POST Insert
PUT Update
DELETE Delete
OPTIONS Allowed Verbs
HEAD Headers Only
![Page 18: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/18.jpg)
HTTP VerbsGET Read
POST Insert
PUT Update
DELETE Delete
OPTIONS Allowed Verbs
HEAD Headers Only
Safe
Unsafe
Idempotent
![Page 19: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/19.jpg)
HTTP Nouns
•google.com/
•goodreads.com/books/Earnest-Cline/Ready-Player-One
•cfobjective.com/sessions/rest-apis-easier-than-you-imagined/
![Page 20: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/20.jpg)
<form action=”http://...” method=”POST”>
</form>
![Page 21: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/21.jpg)
<form action=”http://...” method=”POST”>
</form>
Noun
![Page 22: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/22.jpg)
<form action=”http://...” method=”POST”>
</form>
NounVerb
![Page 23: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/23.jpg)
<form action=”http://...” method=”POST”>
</form>
NounVerb
<input type=”hidden” name=”foo” value=”bar” />
Request Data
![Page 24: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/24.jpg)
Data FormatHTML: text/html
Image: image/jpeg
JSON: application/json
XML: application/xml
ZIP: application/octet-stream
![Page 25: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/25.jpg)
HTTP Status Codes
• 2xx = Success
• 3xx = Redirect
• 4xx = Client Error
• 5xx = Server Error
![Page 26: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/26.jpg)
Do Not Write This Down
This will not be on the test
![Page 27: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/27.jpg)
Raw Request$ telnet www.google.com 80Trying 173.194.73.104...Connected to www.google.com.Escape character is '^]'.GET /index.html HTTP/1.1Host: www.google.com{blank line}
![Page 28: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/28.jpg)
Raw ResponseHTTP/1.1 200 OKDate: Sat, 11 May 2013 18:29:45 GMT[...]X-XSS-Protection: 1; mode=blockX-Frame-Options: SAMEORIGINTransfer-Encoding: chunked
<!doctype html><html..........
}ResponseHeaders
![Page 29: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/29.jpg)
Web APIs work similarly
![Page 30: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/30.jpg)
Raw RequestPOST /api/v1/tweets HTTP/1.1Host: twitter.comContent-Type: application/jsonAccept: application/json, */*;q=0.9User-Agent: MyTwitterApp{
“username”: “AdamTuttle”,“tweet”: “Hello, #CFObjective!”
}[blank line]
![Page 31: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/31.jpg)
Raw ResponseHTTP/1.1 201 Tweet CreatedContent-Type: application/json; charset=UTF-8{
...}
![Page 32: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/32.jpg)
<form action=”http://.../foo/bar” method=”POST”>
</form>
<input type=”hidden” name=”foo” value=”bar” />
![Page 33: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/33.jpg)
POST /....../foo/barHost: www.example.comContent-Type: x-www-form-urlencodedAccept: application/json
foo=bar&flap=jacks
![Page 34: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/34.jpg)
POST /....../foo/barHost: www.example.comContent-Type: x-www-form-urlencodedAccept: application/json
foo=bar&flap=jacks
No question mark
![Page 35: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/35.jpg)
Creating REST APIs with ColdFusion*
*Using Taffy
![Page 36: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/36.jpg)
Choices• Taffy
• Mach-II
• ColdBox
• Relaxation
• Powernap
• RestfulCF
• CF10
![Page 37: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/37.jpg)
Why I (still) <3 Taffy• Simplest, Most-concise syntax
• Easily extended (security layer, etc)
• Doesn’t require access to CFAdmin
• Portable (Railo, CF8+ supported)
• Plays fine with any app framework
• ONLY Convention-over-Config option (CF10?)
• Open Source
![Page 38: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/38.jpg)
Your FirstTaffy-powered API
![Page 39: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/39.jpg)
Application.cfc
component extends=”taffy.core.api” {}
index.cfm
<!--- this space intentionally blank--->
![Page 40: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/40.jpg)
![Page 41: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/41.jpg)
An API w/ Results... that fits into a
Tweet
![Page 42: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/42.jpg)
Application.cfccomponent extends=”taffy.core.api”{}
index.cfm
resources/hi.cfccomponent extends = ”taffy.core.resource” taffy_uri = ”/hi”{ function get(){ return representationOf(“hi”); }}
![Page 43: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/43.jpg)
Application.cfccomponent extends=”taffy.core.api”{}
index.cfm
resources/hi.cfccomponent extends = ”taffy.core.resource” taffy_uri = ”/hi”{ function get(){ return representationOf(“hi”); }}
36
104
![Page 44: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/44.jpg)
![Page 45: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/45.jpg)
![Page 46: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/46.jpg)
![Page 47: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/47.jpg)
![Page 48: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/48.jpg)
![Page 49: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/49.jpg)
Anatomy of an API
![Page 50: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/50.jpg)
Anatomy of an API
Application.cfcindex.cfm/resources/...
![Page 51: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/51.jpg)
Application.cfccomponent extends=”taffy.core.api” {
variables.framework = {};
function applicationStartEvent(){} function requestStartEvent(){} function onTaffyRequest(){}
}
![Page 52: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/52.jpg)
index.cfm
![Page 53: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/53.jpg)
Resources
• Live in /resources subfolder• Each resource defines its own URI• Only implemented verbs are allowed• Collections vs. Members
![Page 54: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/54.jpg)
Resources
component extends=”taffy.core.resource”taffy_uri=”/foo/{fooId}” {
public function get(fooId){} public function delete(fooId){}
}
![Page 55: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/55.jpg)
3 Data Input Options
![Page 56: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/56.jpg)
Tokens & Query Params
• Mapped by name to method args
• Tokens are the same for every method in a resource CFC and always required (otherwise 404)
• Query Params are optional; also passed by name
![Page 57: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/57.jpg)
Simple Inputcomponent extends=”taffy.core.resource” taffy_uri=”/foo/{fooId}” {
function get(fooId, optional string city){ //... }}
<cfargument name=”city” required=”false” />
/api/index.cfm/foo/17?city=Philadelphia
![Page 58: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/58.jpg)
Simple Inputcomponent extends=”taffy.core.resource” taffy_uri=”/foo/{fooId}” {
function get(fooId, optional string city){ //... }}
<cfargument name=”city” required=”false” />
/api/index.cfm/foo/17?city=Philadelphia
![Page 59: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/59.jpg)
Simple Inputcomponent extends=”taffy.core.resource” taffy_uri=”/foo/{fooId}” {
function get(fooId, optional string city){ //... }}
<cfargument name=”city” required=”false” />
/api/index.cfm/foo/17?city=Philadelphia
![Page 60: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/60.jpg)
Simple Inputcomponent extends=”taffy.core.resource” taffy_uri=”/foo/{fooId}” {
function get(fooId, optional string city){ //... }}
<cfargument name=”city” required=”false” />
/api/index.cfm/foo/17?city=Philadelphia
![Page 61: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/61.jpg)
Simple Inputcomponent extends=”taffy.core.resource” taffy_uri=”/foo/{fooId}” {
function get(fooId, optional string city){ //... }}
<cfargument name=”city” required=”false” />
/api/index.cfm/foo/17?city=Philadelphia
![Page 62: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/62.jpg)
Request Body InputTaffy Supports JSON and Form-encoded bodies as long as you set the Content-Type header
{“foo”:”bar baz”,”baz”:true}
foo=bar%20baz&baz=true
![Page 63: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/63.jpg)
Data Output
![Page 64: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/64.jpg)
Returning DatarepresentationOf method abstracts serialization
component extends=”taffy.core.resource”taffy_uri=”/foo” {
public function get(){ var querySvc = new Query(); //... return representationOf( someQuery ); }
}
![Page 65: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/65.jpg)
Returning DatarepresentationOf method abstracts serialization
component extends=”taffy.core.resource”taffy_uri=”/foo” {
public function get(){ var querySvc = new Query(); //... return representationOf( myStruct ); }
}
![Page 66: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/66.jpg)
Returning DatarepresentationOf method abstracts serialization
component extends=”taffy.core.resource”taffy_uri=”/foo” {
public function get(){ var querySvc = new Query(); //... return representationOf( myArray ); }
}
![Page 67: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/67.jpg)
ColdFusion serializes queries ... abnormally.
{"COLUMNS":["COL1","COL2","COL3"],"DATA":[[3,3,true]]}
Taffy’s queryToArray() helper convertsqueries to an array of structures
[ {"CoL1":3,"col2":3,"col3":true}, {"CoL1":4,"col2":4,"col3":false}]
queryToArray()
![Page 68: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/68.jpg)
queryToArray()
return representationOf(queryToArray( myQuery )
);
![Page 69: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/69.jpg)
Response Headersreturn representationOf( ...).withStatus( 201, “Created”).withHeaders( { “X-MY-HEADER” = “My header value” });
![Page 70: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/70.jpg)
Empty Success
return noData().withStatus(201, “Created”);
return noData();
![Page 71: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/71.jpg)
More Advancedgithub.com/atuttle/Taffy/wiki
![Page 72: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/72.jpg)
Dependency Injection/resources/FooService.cfc
/resources/FooCollection.cfc
component { function doStuff(){...}; }
component extends=”taffy.core.resource” ...{ property name=”FooService”;
function get(){ local.foo = this.FooService.doStuff(); //... }}
![Page 73: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/73.jpg)
Resource Subfolders/resources/fooCollection.cfc “fooCollection”
/resources/Cat/Grumpy.cfc “CatGrumpy”
/resources/Services/Old/User.cfc “ServicesOldUser”
Bean Nam
e Generation
![Page 74: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/74.jpg)
• Custom Token Regex
• Intercept requests w/ onTaffyRequest
• 3rd Party Bean Factories
• Verb:Method mapping w/ metadata
• Custom result serializers
• Environment specific config
• ETags for result caching
• ... much, much, much more
![Page 75: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/75.jpg)
Adding an API to an existing App
![Page 76: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/76.jpg)
Shared State
• Subfolder supported, not required
• Enable by using the same Application Name
• Shared variables*
*with great power comes great responsibility
![Page 77: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/77.jpg)
Best Practices
![Page 78: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/78.jpg)
Separate Collections &
Members
![Page 79: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/79.jpg)
Version yourAPI from day 1.
/api/v1/foo/bar
![Page 80: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/80.jpg)
Thoughtful URIs
![Page 81: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/81.jpg)
Human-Readable URIs
![Page 82: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/82.jpg)
Token vsQuery String
![Page 83: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/83.jpg)
PUT or POST?
![Page 84: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/84.jpg)
HATEOAS
![Page 85: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/85.jpg)
HTTP Status Codes are your friend
![Page 86: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/86.jpg)
Antipatterns
![Page 87: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/87.jpg)
I hate you.
If you code like this...
![Page 88: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/88.jpg)
GET request writes data
![Page 89: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/89.jpg)
2+ requests / task
![Page 90: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/90.jpg)
200 Error
![Page 91: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/91.jpg)
Using Cookies
![Page 92: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/92.jpg)
Getting SupportMailing List: bit.ly/taffy-users
IRC: #coldfusion on freenode and dalnetTweet me: @AdamTuttle
![Page 93: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/93.jpg)
Thank You
![Page 94: REST API's: Easier Than You Imagined](https://reader033.fdocuments.us/reader033/viewer/2022042601/555c22a4d8b42a09438b4a59/html5/thumbnails/94.jpg)