View
115
Download
2
Category
Preview:
Citation preview
REST w praktyce...tej dobrej i tej złej
Jakub Kubrynski
jk@devskiller.com / @jkubrynski 1 / 42
jk@devskiller.com / @jkubrynski 2 / 42
"The Code is more what you'd call guidelines than actual rules. Welcomeaboard the Black Pearl, Miss Turner"
-- Cpt. Hector Barbossa to Elizabeth Swann
RT Ben Hale
jk@devskiller.com / @jkubrynski 3 / 42
Formal REST constraintsClient-Server
Stateless
Cache
Interface / Uniform Contract
Layered System
jk@devskiller.com / @jkubrynski 4 / 42
Richardson maturity model
http://martinfowler.com/articles/richardsonMaturityModel.html
jk@devskiller.com / @jkubrynski 5 / 42
POST vs PUT
jk@devskiller.com / @jkubrynski 6 / 42
POST vs PUTPOST creates new resources
jk@devskiller.com / @jkubrynski 7 / 42
POST vs PUTPOST creates new resources
PUT updates existing resources
PUT can create resource if ID is already known
jk@devskiller.com / @jkubrynski 8 / 42
REST without PUTsfor everyone who hates CRUD
jk@devskiller.com / @jkubrynski 9 / 42
REST without PUTsfor everyone who hates CRUD
all changes driven by events
POST to /domainEvents
jk@devskiller.com / @jkubrynski 10 / 42
Maybe PATCH?partial update concept
no "out of the box" support
jk@devskiller.com / @jkubrynski 11 / 42
Cachingbe aware - especially IE caches aggressively
better disable caching
jk@devskiller.com / @jkubrynski 12 / 42
Cache headerscache-control: public, max-age=0, no-cache
public / private
no-cacheno-storemax-ages-maxage
jk@devskiller.com / @jkubrynski 13 / 42
ETagIf-None-Match header set to entity uuid
if matches then "304 Not Modified"
uuid can be smart - entity id and version
"User:34652:15"
jk@devskiller.com / @jkubrynski 14 / 42
Compressionreduces response size dramatically
10 times smaller response is nothing special
usually really easy to enable
jk@devskiller.com / @jkubrynski 15 / 42
HATEOAS
jk@devskiller.com / @jkubrynski 16 / 42
HATEOASself-descriptive
jk@devskiller.com / @jkubrynski 17 / 42
HATEOASself-descriptive
client understands hypermedia
{ "name" : "Alice", "email" : "alice_at_inchains.org" "links" : [ { "rel" : "self", "href" : "/customers/1213" }, { "rel" : "currentOrder", "href" : "/orders/14312" }, { "rel" : "loyaltyAccount", "href" : "/accounts/11234" } ]}
HTTP/1.1 201 CreatedLocation: http://api.myshop.com/orders/1234
jk@devskiller.com / @jkubrynski 18 / 42
@DanaDanger HTTP codes classification20x: cool
30x: ask that dude over there
40x: you fucked up
50x: we fucked up
jk@devskiller.com / @jkubrynski 19 / 42
Exceptionshide sensitive information
jk@devskiller.com / @jkubrynski 20 / 42
Exceptionshide sensitive information
but include detailed information
{ "status" : 400, "code" : 40483, "message" : "Incorrect body signature", "moreInfo" : "http://www.mycompany.com/errors/40483"}
jk@devskiller.com / @jkubrynski 21 / 42
API Versioningdon't even think aboutapi.domain.com/v2/orders
URIs to the same resources should be fixedbetween versions
jk@devskiller.com / @jkubrynski 22 / 42
API Versioningdon't even think aboutapi.domain.com/v2/orders
URIs to the same resources should be fixedbetween versions
use Content-Type
1 version: application/vnd.domain+json
2 version: application/vnd.domain.v2+json
jk@devskiller.com / @jkubrynski 23 / 42
Filtering and sortingGET /reviews?rating=5
GET /reviews?rating=5&sortAsc=author
jk@devskiller.com / @jkubrynski 24 / 42
Filtering and sortingGET /reviews?rating=5
GET /reviews?rating=5&sortAsc=author
Dynamic queries are easier in POST body
jk@devskiller.com / @jkubrynski 25 / 42
Filtering and sortingGET /reviews?rating=5
GET /reviews?rating=5&sortAsc=author
Dynamic queries are easier in POST body
POST /reviews/searches
GET /reviews/searches/23?page=2
jk@devskiller.com / @jkubrynski 26 / 42
Documentationrunnable with examples
Swagger
jk@devskiller.com / @jkubrynski 27 / 42
jk@devskiller.com / @jkubrynski 28 / 42
Stateless or not?password hashing cost
session replication
load-balancing
jk@devskiller.com / @jkubrynski 29 / 42
Stateless or not?password hashing cost
session replication
load-balancing
...
stateless session?
jk@devskiller.com / @jkubrynski 30 / 42
SecuritySQL Injection
XSS
CSRF
XXE
jk@devskiller.com / @jkubrynski 31 / 42
CSRF - Cross-site request forgery<img src="https://api.mybank.com/transfers/from/1233/to/1234/amount/5000">
<form action="https://api.mybank.com/transfers" method="POST"> <input type="hidden" name="from" value="1233"/> <input type="hidden" name="to" value="1234"/> <input type="hidden" name=amount" value="5000"/> <input type="submit" value="Celebrity Nude Photos!"/></form>
jk@devskiller.com / @jkubrynski 32 / 42
CSRF - Cross-site request forgery<img src="https://api.mybank.com/transfers/from/1233/to/1234/amount/5000">
<form action="https://api.mybank.com/transfers" method="POST"> <input type="hidden" name="from" value="1233"/> <input type="hidden" name="to" value="1234"/> <input type="hidden" name=amount" value="5000"/> <input type="submit" value="Celebrity Nude Photos!"/></form>
One time request tokens
Correct CORS headers
jk@devskiller.com / @jkubrynski 33 / 42
CORS - Cross Origin Requests SharingPreflight request
OPTIONS /cors HTTP/1.1Origin: http://www.domain.comAccess-Control-Request-Method: PUTAccess-Control-Request-Headers: X-Custom-HeaderHost: api.mydomain.orgAccept-Language: en-USConnection: keep-aliveUser-Agent: Mozilla/5.0...
Preflight response
Access-Control-Allow-Origin: http://www.domain.comAccess-Control-Allow-Methods: GET, POST, PUTAccess-Control-Allow-Headers: X-Custom-HeaderContent-Type: text/html; charset=utf-8
jk@devskiller.com / @jkubrynski 34 / 42
XML External Entity<?xml version="1.0" encoding="utf-8"?><comment> <text>Yeah! I like it!</text></comment>
jk@devskiller.com / @jkubrynski 35 / 42
XML External Entity<?xml version="1.0" encoding="utf-8"?><comment> <text>Yeah! I like it!</text></comment>
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE myentity [ <!ENTITY a "Yeah! I like it!"> ]><comment> <text>&a;</text></comment>
jk@devskiller.com / @jkubrynski 36 / 42
# XML External Entity
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE myentity [ <!ENTITY a SYSTEM "/etc/passwd"> ]><comment> <text>&a;</text></comment>
jk@devskiller.com / @jkubrynski 37 / 42
# XML External Entity
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE myentity [ <!ENTITY a SYSTEM "/etc/passwd"> ]><comment> <text>&a;</text></comment>
<?xml version="1.0" encoding="utf-8"?><comment> <text>root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin sync:x:5:0:sync:/sbin:/bin/sync shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown halt:x:7:0:halt:/sbin:/sbin/halt ..... </text></comment>
jk@devskiller.com / @jkubrynski 38 / 42
XML External Entity<?xml version="1.0" encoding="utf-8"?><!DOCTYPE myentity [<!ENTITY a "abcdefghij1234567890" ><!ENTITY b "&a;&a;&a;&a;&a;&a;&a;&a;&a;&a" ><!ENTITY c "&b;&b;&b;&b;&b;&b;&b;&b;&b;&b;" ><!ENTITY d "&c;&c;&c;&c;&c;&c;&c;&c;&c;&c;" >...<!ENTITY h "&g;&g;&g;&g;&g;&g;&g;&g;&g;&g;" >]><comment> <text>&h;</text></comment>
jk@devskiller.com / @jkubrynski 39 / 42
http://knowyourmeme.com/photos/531557 thx to @mihn
jk@devskiller.com / @jkubrynski 40 / 42
DDD training?
jk@devskiller.com / @jkubrynski 41 / 42
Thanks!
jk@devskiller.com / @jkubrynski 42 / 42
Recommended