SlideShare uma empresa Scribd logo
1 de 48
Baixar para ler offline
The thin line between RESTful and AWful 
Jakub Kubrynski 
jk@devskiller.com / @jkubrynski 1 / 48
jk@devskiller.com / @jkubrynski 2 / 48
"The Code is more what you'd call guidelines than actual rules. Welcome 
aboard the Black Pearl, Miss Turner" 
-- Cpt. Hector Barbossa to Elizabeth Swann 
RT Ben Hale 
jk@devskiller.com / @jkubrynski 3 / 48
Formal REST constraints 
Client-Server 
Stateless 
Cache 
Interface / Uniform Contract 
Layered System 
jk@devskiller.com / @jkubrynski 4 / 48
Richardson maturity model 
http://martinfowler.com/articles/richardsonMaturityModel.html 
jk@devskiller.com / @jkubrynski 5 / 48
POST vs PUT 
jk@devskiller.com / @jkubrynski 6 / 48
POST vs PUT 
POST creates new resources 
jk@devskiller.com / @jkubrynski 7 / 48
POST vs PUT 
POST creates new resources 
PUT updates existing resources 
PUT can create resource if ID is already known 
jk@devskiller.com / @jkubrynski 8 / 48
Maybe PATCH? 
no "out of the box" support 
jk@devskiller.com / @jkubrynski 9 / 48
Maybe PATCH? 
no "out of the box" support 
partial update 
@RequestMapping(value = "/{id}", method = PATCH) 
public void updateArticle(HttpServletRequest request, @PathVariable("id") String id) { 
Article currentArticle = repository.findOne(id); 
Article updatedArticle = objectMapper.readerForUpdating(currentArticle) 
.readValue(request.getReader()); 
repository.save(updatedArticle); 
} 
jk@devskiller.com / @jkubrynski 10 / 48
Caching 
be aware - especially IE caches aggressively 
jk@devskiller.com / @jkubrynski 11 / 48
Caching 
be aware - especially IE caches aggressively 
disable caching 
@Configuration 
public class RestConfig extends WebMvcConfigurerAdapter { 
@Override 
public void addInterceptors(InterceptorRegistry registry) { 
WebContentInterceptor webContentInterceptor = new WebContentInterceptor(); 
webContentInterceptor.setCacheSeconds(0); 
registry.addInterceptor(webContentInterceptor); 
} 
} 
jk@devskiller.com / @jkubrynski 12 / 48
Cache headers 
cache-control: public, max-age=0, no-cache 
public / private 
no-cache 
no-store 
max-age 
s-maxage 
jk@devskiller.com / @jkubrynski 13 / 48
Cache headers 
cache-control: public, max-age=0, no-cache 
public / private 
no-cache 
no-store 
max-age 
s-maxage 
ETag 
If-None-Match: "0d41d8cd98f00b204e9800998ecf8427e" 
Spring brings ShallowEtagHeaderFilter 
jk@devskiller.com / @jkubrynski 14 / 48
Compression 
reduces response size dramatically 
in Tomcat extend Connector with 
compression="on" 
compressionMinSize="2048" 
noCompressionUserAgents="gozilla, traviata" 
compressableMimeType="text/html,text/xml" 
jk@devskiller.com / @jkubrynski 15 / 48
HATEOAS 
self-descriptive 
client understands hypermedia 
{ 
"name": "Alice", 
"links": [ 
{ "rel": "self", "href": "/customers/1213" }, 
{ "rel": "parent", "href": "/customers/14" }, 
{ "rel": "currentOrder", "href": "/orders/14312" } 
] 
} 
HTTP/1.1 201 Created 
Location: http://api.mydomain.com/orders/1234 
jk@devskiller.com / @jkubrynski 16 / 48
HATEOAS in Spring 
public class Customer extends ResourceSupport { ... } 
// or wrap entity into Resource object 
jk@devskiller.com / @jkubrynski 17 / 48
HATEOAS in Spring 
public class Customer extends ResourceSupport { ... } 
// or wrap entity into Resource object 
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.*; 
public HttpEntity<Customer> get(@PathVariable("id") String customerId) { 
Customer customer = repository.findOne(customerId); 
String pId = customer.getBoss(); 
String oId = customer.currentOrderId(); 
customer.add(linkTo(methodOn(CustomerController.class).get(customerId)).withSelfRel()); 
customer.add(linkTo(methodOn(CustomerController.class).get(pId)).withRel("parent")); 
customer.add(linkTo(methodOn(OrderController.class).get(oId)).withRel("currentOrder")); 
return new ResponseEntity<Customer>(customer, HttpStatus.OK); 
} 
public ResponseEntity create(@RequestBody Customer customer) { 
String id = repository.save(customer); 
return ResponseEntity.created(linkTo(CustomerController.class).slash(id).toUri()) 
.build(); 
} 
jk@devskiller.com / @jkubrynski 18 / 48
@DanaDanger HTTP codes classification 
20x: cool 
30x: ask that dude over there 
40x: you fucked up 
50x: we fucked up 
jk@devskiller.com / @jkubrynski 19 / 48
Exceptions 
include detailed information 
{ 
"status": 400, 
"code": 40483, 
"message": "Incorrect body signature", 
"moreInfo": "http://www.mycompany.com/errors/40483" 
} 
jk@devskiller.com / @jkubrynski 20 / 48
Exceptions 
include detailed information 
{ 
"status": 400, 
"code": 40483, 
"message": "Incorrect body signature", 
"moreInfo": "http://www.mycompany.com/errors/40483" 
} 
hide stacktrace 
jk@devskiller.com / @jkubrynski 21 / 48
Handling Spring MVC exceptions 
@ControllerAdvice 
public class MyExceptionHandler extends ResponseEntityExceptionHandler { 
/* Handling framework exceptions */ 
@Override 
protected ResponseEntity<Object> handleExceptionInternal(Exception ex, Object body, 
HttpHeaders headers, HttpStatus status, WebRequest request) { 
LOG.error("Spring MVC exception occurred", ex); 
return super.handleExceptionInternal(ex, body, headers, status, request); 
} 
/* Handling application exceptions */ 
@ResponseStatus(value = HttpStatus.NOT_FOUND) 
@ExceptionHandler(ResourceNotFoundException.class) 
public void handleResourceNotFound() { 
} 
} 
jk@devskiller.com / @jkubrynski 22 / 48
API Versioning 
don't even think about 
api.domain.com/v2/orders 
URIs to the same resources should be fixed between 
versions 
jk@devskiller.com / @jkubrynski 23 / 48
API Versioning 
don't even think about 
api.domain.com/v2/orders 
URIs to the same resources should be fixed between 
versions 
use Content-Type 
1 version: application/vnd.domain+json 
2 version: application/vnd.domain.v2+json 
jk@devskiller.com / @jkubrynski 24 / 48
Filtering and sorting 
GET /reviews?rating=5 
GET /reviews?rating=5&sortAsc=author 
jk@devskiller.com / @jkubrynski 25 / 48
Filtering and sorting 
GET /reviews?rating=5 
GET /reviews?rating=5&sortAsc=author 
Dynamic queries are easier in POST body 
jk@devskiller.com / @jkubrynski 26 / 48
Filtering and sorting 
GET /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 27 / 48
Documentation 
runnable with examples 
Swagger 
jk@devskiller.com / @jkubrynski 28 / 48
jk@devskiller.com / @jkubrynski 29 / 48
Stateless or not? 
password hashing cost 
session replication 
load-balancing 
jk@devskiller.com / @jkubrynski 30 / 48
Stateless or not? 
password hashing cost 
session replication 
load-balancing 
... 
stateless session? 
jk@devskiller.com / @jkubrynski 31 / 48
Avoiding session creation in Spring 
@EnableWebSecurity 
public class SpringSecurity extends WebSecurityConfigurerAdapter { 
@Override 
protected void configure(HttpSecurity http) throws Exception { 
http 
.csrf().disable() 
.authorizeRequests() 
.antMatchers("/secure/**").fullyAuthenticated() 
.and() 
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.NEVER) 
.and() 
.httpBasic(); 
} 
} 
jk@devskiller.com / @jkubrynski 32 / 48
Security 
SQL Injection 
XSS 
CSRF 
XXE 
jk@devskiller.com / @jkubrynski 33 / 48
HQL Injection 
List<Product> products = em.createQuery( 
"SELECT p FROM Product p where p.category = '" + categ + "'", Product.class) 
.getResultList(); 
jk@devskiller.com / @jkubrynski 34 / 48
HQL Injection 
List<Product> products = em.createQuery( 
"SELECT p FROM Product p where p.category = '" + categ + "'", Product.class) 
.getResultList(); 
categ = ' OR '1'='1 
jk@devskiller.com / @jkubrynski 35 / 48
HQL Injection 
List<Product> products = em.createQuery( 
"SELECT p FROM Product p where p.category = '" + categ + "'", Product.class) 
.getResultList(); 
categ = ' OR '1'='1 
SELECT __fields__ FROM products WHERE category = '' OR '1'='1' 
jk@devskiller.com / @jkubrynski 36 / 48
HQL Injection 
List<Product> products = em.createQuery( 
"SELECT p FROM Product p where p.category = '" + categ + "'", Product.class) 
.getResultList(); 
categ = ' OR '1'='1 
SELECT __fields__ FROM products WHERE category = '' OR '1'='1' 
List<Product> products = em.createQuery( 
"SELECT p FROM Product p where p.category = :categ", Product.class) 
.setParameter("categ", categ) 
.getResultList(); 
jk@devskiller.com / @jkubrynski 37 / 48
HQL Injection 
List<Product> products = em.createQuery( 
"SELECT p FROM Product p where p.category = '" + categ + "'", Product.class) 
.getResultList(); 
categ = ' OR '1'='1 
SELECT __fields__ FROM products WHERE category = '' OR '1'='1' 
List<Product> products = em.createQuery( 
"SELECT p FROM Product p where p.category = :categ", Product.class) 
.setParameter("categ", categ) 
.getResultList(); 
SELECT __fields__ FROM products WHERE category = ' OR ''1''=''1''' 
jk@devskiller.com / @jkubrynski 38 / 48
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 39 / 48
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 40 / 48
CORS - Cross Origin Requests Sharing 
Preflight request 
OPTIONS /cors HTTP/1.1 
Origin: http://www.domain.com 
Access-Control-Request-Method: PUT 
Access-Control-Request-Headers: X-Custom-Header 
Host: api.mydomain.org 
Accept-Language: en-US 
Connection: keep-alive 
User-Agent: Mozilla/5.0... 
Preflight response 
Access-Control-Allow-Origin: http://www.domain.com 
Access-Control-Allow-Methods: GET, POST, PUT 
Access-Control-Allow-Headers: X-Custom-Header 
Content-Type: text/html; charset=utf-8 
jk@devskiller.com / @jkubrynski 41 / 48
XML External Entity 
<?xml version="1.0" encoding="utf-8"?> 
<comment> 
<text>Yeah! I like it!</text> 
</comment> 
jk@devskiller.com / @jkubrynski 42 / 48
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 43 / 48
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 44 / 48
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 45 / 48
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 46 / 48
http://knowyourmeme.com/photos/531557 thx to @mihn 
jk@devskiller.com / @jkubrynski 47 / 48
Thanks! 
jk@devskiller.com / @jkubrynski 48 / 48

Mais conteúdo relacionado

Destaque

JDD2014: Using ASCII art to analyzeyour source code with NEO4J and OSS tools ...
JDD2014: Using ASCII art to analyzeyour source code with NEO4J and OSS tools ...JDD2014: Using ASCII art to analyzeyour source code with NEO4J and OSS tools ...
JDD2014: Using ASCII art to analyzeyour source code with NEO4J and OSS tools ...PROIDEA
 
PLNOG14: DNS jako niedoceniana broń ISP w walce ze złośliwym oprogramowaniem ...
PLNOG14: DNS jako niedoceniana broń ISP w walce ze złośliwym oprogramowaniem ...PLNOG14: DNS jako niedoceniana broń ISP w walce ze złośliwym oprogramowaniem ...
PLNOG14: DNS jako niedoceniana broń ISP w walce ze złośliwym oprogramowaniem ...PROIDEA
 
PLNOG14: Zastosowanie NFV, symulacja sieci VIRL/CML - Marek Moskal
PLNOG14: Zastosowanie NFV, symulacja sieci VIRL/CML - Marek MoskalPLNOG14: Zastosowanie NFV, symulacja sieci VIRL/CML - Marek Moskal
PLNOG14: Zastosowanie NFV, symulacja sieci VIRL/CML - Marek MoskalPROIDEA
 
PLNOG14: Security Operations Center, wyższy poziom bezpieczeństwa - Tomasz Ta...
PLNOG14: Security Operations Center, wyższy poziom bezpieczeństwa - Tomasz Ta...PLNOG14: Security Operations Center, wyższy poziom bezpieczeństwa - Tomasz Ta...
PLNOG14: Security Operations Center, wyższy poziom bezpieczeństwa - Tomasz Ta...PROIDEA
 
PLNOG14: DNS, czyli co nowego w świecie DNS-ozaurów - Adam Obszyński
PLNOG14: DNS, czyli co nowego w świecie DNS-ozaurów - Adam ObszyńskiPLNOG14: DNS, czyli co nowego w świecie DNS-ozaurów - Adam Obszyński
PLNOG14: DNS, czyli co nowego w świecie DNS-ozaurów - Adam ObszyńskiPROIDEA
 
PLNOG 13: Grzegorz Janoszka: Peering vs Tranzyt – Czy peering jest naprawdę s...
PLNOG 13: Grzegorz Janoszka: Peering vs Tranzyt – Czy peering jest naprawdę s...PLNOG 13: Grzegorz Janoszka: Peering vs Tranzyt – Czy peering jest naprawdę s...
PLNOG 13: Grzegorz Janoszka: Peering vs Tranzyt – Czy peering jest naprawdę s...PROIDEA
 
4Developers 2015: Legacy Code, szkoła przetrwania - Katarzyna Żmuda
4Developers 2015: Legacy Code, szkoła przetrwania - Katarzyna Żmuda4Developers 2015: Legacy Code, szkoła przetrwania - Katarzyna Żmuda
4Developers 2015: Legacy Code, szkoła przetrwania - Katarzyna ŻmudaPROIDEA
 
PLNOG 13: Krystian Baniak: Value Added Services Platform
PLNOG 13: Krystian Baniak: Value Added Services PlatformPLNOG 13: Krystian Baniak: Value Added Services Platform
PLNOG 13: Krystian Baniak: Value Added Services PlatformPROIDEA
 
4Developers 2015: Clean JavaScript code - only dream or reality - Sebastian Ł...
4Developers 2015: Clean JavaScript code - only dream or reality - Sebastian Ł...4Developers 2015: Clean JavaScript code - only dream or reality - Sebastian Ł...
4Developers 2015: Clean JavaScript code - only dream or reality - Sebastian Ł...PROIDEA
 
4Developers 2015: Procesy biznesowe z perspektywy atakującego - Mateusz Olejarka
4Developers 2015: Procesy biznesowe z perspektywy atakującego - Mateusz Olejarka4Developers 2015: Procesy biznesowe z perspektywy atakującego - Mateusz Olejarka
4Developers 2015: Procesy biznesowe z perspektywy atakującego - Mateusz OlejarkaPROIDEA
 
PLNOG 13: M. Czerwonka, T. Kossut: IPv6 in mobile network
PLNOG 13: M. Czerwonka, T. Kossut: IPv6 in mobile networkPLNOG 13: M. Czerwonka, T. Kossut: IPv6 in mobile network
PLNOG 13: M. Czerwonka, T. Kossut: IPv6 in mobile networkPROIDEA
 
JDD2014: JEE'ish development without hassle - Jakub Marchwicki
JDD2014: JEE'ish development without hassle - Jakub MarchwickiJDD2014: JEE'ish development without hassle - Jakub Marchwicki
JDD2014: JEE'ish development without hassle - Jakub MarchwickiPROIDEA
 
PLNOG14: Darmowe narzędzia wspomagające proces zabezpieczania Twojej firmy - ...
PLNOG14: Darmowe narzędzia wspomagające proces zabezpieczania Twojej firmy - ...PLNOG14: Darmowe narzędzia wspomagające proces zabezpieczania Twojej firmy - ...
PLNOG14: Darmowe narzędzia wspomagające proces zabezpieczania Twojej firmy - ...PROIDEA
 
PLNOG 13: Emil Gągała: EVPN – rozwiązanie nie tylko dla Data Center
PLNOG 13: Emil Gągała: EVPN – rozwiązanie nie tylko dla Data CenterPLNOG 13: Emil Gągała: EVPN – rozwiązanie nie tylko dla Data Center
PLNOG 13: Emil Gągała: EVPN – rozwiązanie nie tylko dla Data CenterPROIDEA
 
4Developers 2015: Varnish tips & tricks - Piotr Pasich
4Developers 2015: Varnish tips & tricks - Piotr Pasich4Developers 2015: Varnish tips & tricks - Piotr Pasich
4Developers 2015: Varnish tips & tricks - Piotr PasichPROIDEA
 
PLNOG14: Zupa internetowa - jak przyrządzić smaczne danie z IXów, Data Center...
PLNOG14: Zupa internetowa - jak przyrządzić smaczne danie z IXów, Data Center...PLNOG14: Zupa internetowa - jak przyrządzić smaczne danie z IXów, Data Center...
PLNOG14: Zupa internetowa - jak przyrządzić smaczne danie z IXów, Data Center...PROIDEA
 
Magnus Jirström, Lund University at SIANI Annual Meeting 2014
Magnus Jirström, Lund University at SIANI Annual Meeting 2014 Magnus Jirström, Lund University at SIANI Annual Meeting 2014
Magnus Jirström, Lund University at SIANI Annual Meeting 2014 SIANI
 
Chemical Ecology for Sustainable Sorghum Production in Ethiopia
Chemical Ecology for Sustainable Sorghum Production in EthiopiaChemical Ecology for Sustainable Sorghum Production in Ethiopia
Chemical Ecology for Sustainable Sorghum Production in EthiopiaSIANI
 
Priorities and Strategic Initiatives for Securing Forest and Community Land ...
 Priorities and Strategic Initiatives for Securing Forest and Community Land ... Priorities and Strategic Initiatives for Securing Forest and Community Land ...
Priorities and Strategic Initiatives for Securing Forest and Community Land ...SIANI
 
Cattle in the Kalahari: Breeding Gendered Change
Cattle in the Kalahari: Breeding Gendered Change Cattle in the Kalahari: Breeding Gendered Change
Cattle in the Kalahari: Breeding Gendered Change SIANI
 

Destaque (20)

JDD2014: Using ASCII art to analyzeyour source code with NEO4J and OSS tools ...
JDD2014: Using ASCII art to analyzeyour source code with NEO4J and OSS tools ...JDD2014: Using ASCII art to analyzeyour source code with NEO4J and OSS tools ...
JDD2014: Using ASCII art to analyzeyour source code with NEO4J and OSS tools ...
 
PLNOG14: DNS jako niedoceniana broń ISP w walce ze złośliwym oprogramowaniem ...
PLNOG14: DNS jako niedoceniana broń ISP w walce ze złośliwym oprogramowaniem ...PLNOG14: DNS jako niedoceniana broń ISP w walce ze złośliwym oprogramowaniem ...
PLNOG14: DNS jako niedoceniana broń ISP w walce ze złośliwym oprogramowaniem ...
 
PLNOG14: Zastosowanie NFV, symulacja sieci VIRL/CML - Marek Moskal
PLNOG14: Zastosowanie NFV, symulacja sieci VIRL/CML - Marek MoskalPLNOG14: Zastosowanie NFV, symulacja sieci VIRL/CML - Marek Moskal
PLNOG14: Zastosowanie NFV, symulacja sieci VIRL/CML - Marek Moskal
 
PLNOG14: Security Operations Center, wyższy poziom bezpieczeństwa - Tomasz Ta...
PLNOG14: Security Operations Center, wyższy poziom bezpieczeństwa - Tomasz Ta...PLNOG14: Security Operations Center, wyższy poziom bezpieczeństwa - Tomasz Ta...
PLNOG14: Security Operations Center, wyższy poziom bezpieczeństwa - Tomasz Ta...
 
PLNOG14: DNS, czyli co nowego w świecie DNS-ozaurów - Adam Obszyński
PLNOG14: DNS, czyli co nowego w świecie DNS-ozaurów - Adam ObszyńskiPLNOG14: DNS, czyli co nowego w świecie DNS-ozaurów - Adam Obszyński
PLNOG14: DNS, czyli co nowego w świecie DNS-ozaurów - Adam Obszyński
 
PLNOG 13: Grzegorz Janoszka: Peering vs Tranzyt – Czy peering jest naprawdę s...
PLNOG 13: Grzegorz Janoszka: Peering vs Tranzyt – Czy peering jest naprawdę s...PLNOG 13: Grzegorz Janoszka: Peering vs Tranzyt – Czy peering jest naprawdę s...
PLNOG 13: Grzegorz Janoszka: Peering vs Tranzyt – Czy peering jest naprawdę s...
 
4Developers 2015: Legacy Code, szkoła przetrwania - Katarzyna Żmuda
4Developers 2015: Legacy Code, szkoła przetrwania - Katarzyna Żmuda4Developers 2015: Legacy Code, szkoła przetrwania - Katarzyna Żmuda
4Developers 2015: Legacy Code, szkoła przetrwania - Katarzyna Żmuda
 
PLNOG 13: Krystian Baniak: Value Added Services Platform
PLNOG 13: Krystian Baniak: Value Added Services PlatformPLNOG 13: Krystian Baniak: Value Added Services Platform
PLNOG 13: Krystian Baniak: Value Added Services Platform
 
4Developers 2015: Clean JavaScript code - only dream or reality - Sebastian Ł...
4Developers 2015: Clean JavaScript code - only dream or reality - Sebastian Ł...4Developers 2015: Clean JavaScript code - only dream or reality - Sebastian Ł...
4Developers 2015: Clean JavaScript code - only dream or reality - Sebastian Ł...
 
4Developers 2015: Procesy biznesowe z perspektywy atakującego - Mateusz Olejarka
4Developers 2015: Procesy biznesowe z perspektywy atakującego - Mateusz Olejarka4Developers 2015: Procesy biznesowe z perspektywy atakującego - Mateusz Olejarka
4Developers 2015: Procesy biznesowe z perspektywy atakującego - Mateusz Olejarka
 
PLNOG 13: M. Czerwonka, T. Kossut: IPv6 in mobile network
PLNOG 13: M. Czerwonka, T. Kossut: IPv6 in mobile networkPLNOG 13: M. Czerwonka, T. Kossut: IPv6 in mobile network
PLNOG 13: M. Czerwonka, T. Kossut: IPv6 in mobile network
 
JDD2014: JEE'ish development without hassle - Jakub Marchwicki
JDD2014: JEE'ish development without hassle - Jakub MarchwickiJDD2014: JEE'ish development without hassle - Jakub Marchwicki
JDD2014: JEE'ish development without hassle - Jakub Marchwicki
 
PLNOG14: Darmowe narzędzia wspomagające proces zabezpieczania Twojej firmy - ...
PLNOG14: Darmowe narzędzia wspomagające proces zabezpieczania Twojej firmy - ...PLNOG14: Darmowe narzędzia wspomagające proces zabezpieczania Twojej firmy - ...
PLNOG14: Darmowe narzędzia wspomagające proces zabezpieczania Twojej firmy - ...
 
PLNOG 13: Emil Gągała: EVPN – rozwiązanie nie tylko dla Data Center
PLNOG 13: Emil Gągała: EVPN – rozwiązanie nie tylko dla Data CenterPLNOG 13: Emil Gągała: EVPN – rozwiązanie nie tylko dla Data Center
PLNOG 13: Emil Gągała: EVPN – rozwiązanie nie tylko dla Data Center
 
4Developers 2015: Varnish tips & tricks - Piotr Pasich
4Developers 2015: Varnish tips & tricks - Piotr Pasich4Developers 2015: Varnish tips & tricks - Piotr Pasich
4Developers 2015: Varnish tips & tricks - Piotr Pasich
 
PLNOG14: Zupa internetowa - jak przyrządzić smaczne danie z IXów, Data Center...
PLNOG14: Zupa internetowa - jak przyrządzić smaczne danie z IXów, Data Center...PLNOG14: Zupa internetowa - jak przyrządzić smaczne danie z IXów, Data Center...
PLNOG14: Zupa internetowa - jak przyrządzić smaczne danie z IXów, Data Center...
 
Magnus Jirström, Lund University at SIANI Annual Meeting 2014
Magnus Jirström, Lund University at SIANI Annual Meeting 2014 Magnus Jirström, Lund University at SIANI Annual Meeting 2014
Magnus Jirström, Lund University at SIANI Annual Meeting 2014
 
Chemical Ecology for Sustainable Sorghum Production in Ethiopia
Chemical Ecology for Sustainable Sorghum Production in EthiopiaChemical Ecology for Sustainable Sorghum Production in Ethiopia
Chemical Ecology for Sustainable Sorghum Production in Ethiopia
 
Priorities and Strategic Initiatives for Securing Forest and Community Land ...
 Priorities and Strategic Initiatives for Securing Forest and Community Land ... Priorities and Strategic Initiatives for Securing Forest and Community Land ...
Priorities and Strategic Initiatives for Securing Forest and Community Land ...
 
Cattle in the Kalahari: Breeding Gendered Change
Cattle in the Kalahari: Breeding Gendered Change Cattle in the Kalahari: Breeding Gendered Change
Cattle in the Kalahari: Breeding Gendered Change
 

Semelhante a JDD2014: What you won't read in books about implementing REST services - Jakub Kubryński

The vJUG talk about jOOQ: Get Back in Control of Your SQL
The vJUG talk about jOOQ: Get Back in Control of Your SQLThe vJUG talk about jOOQ: Get Back in Control of Your SQL
The vJUG talk about jOOQ: Get Back in Control of Your SQLLukas Eder
 
4Developers 2015: REST w praktyce - tej dobrej i tej złej - Jakub Kubryński
4Developers 2015: REST w praktyce - tej dobrej i tej złej - Jakub Kubryński4Developers 2015: REST w praktyce - tej dobrej i tej złej - Jakub Kubryński
4Developers 2015: REST w praktyce - tej dobrej i tej złej - Jakub KubryńskiPROIDEA
 
Static Analysis in IDEA
Static Analysis in IDEAStatic Analysis in IDEA
Static Analysis in IDEAHamletDRC
 
Whatever it takes - Fixing SQLIA and XSS in the process
Whatever it takes - Fixing SQLIA and XSS in the processWhatever it takes - Fixing SQLIA and XSS in the process
Whatever it takes - Fixing SQLIA and XSS in the processguest3379bd
 
Keep your Wicket application in production
Keep your Wicket application in productionKeep your Wicket application in production
Keep your Wicket application in productionMartijn Dashorst
 
Get Back in Control of your SQL with jOOQ - GeekOut by ZeroTurnaround
Get Back in Control of your SQL with jOOQ - GeekOut by ZeroTurnaroundGet Back in Control of your SQL with jOOQ - GeekOut by ZeroTurnaround
Get Back in Control of your SQL with jOOQ - GeekOut by ZeroTurnaroundDataGeekery
 
Solving anything in VCL
Solving anything in VCLSolving anything in VCL
Solving anything in VCLFastly
 
10 Excellent Ways to Secure Your Spring Boot Application - Devoxx Belgium 2019
10 Excellent Ways to Secure Your Spring Boot Application - Devoxx Belgium 201910 Excellent Ways to Secure Your Spring Boot Application - Devoxx Belgium 2019
10 Excellent Ways to Secure Your Spring Boot Application - Devoxx Belgium 2019Matt Raible
 
Bkbiet day2 & 3
Bkbiet day2 & 3Bkbiet day2 & 3
Bkbiet day2 & 3mihirio
 
Arquillian Constellation
Arquillian ConstellationArquillian Constellation
Arquillian ConstellationAlex Soto
 
Spring 3: What's New
Spring 3: What's NewSpring 3: What's New
Spring 3: What's NewTed Pennings
 
10 Excellent Ways to Secure Spring Boot Applications - Okta Webinar 2020
10 Excellent Ways to Secure Spring Boot Applications - Okta Webinar 202010 Excellent Ways to Secure Spring Boot Applications - Okta Webinar 2020
10 Excellent Ways to Secure Spring Boot Applications - Okta Webinar 2020Matt Raible
 
Testing the frontend
Testing the frontendTesting the frontend
Testing the frontendHeiko Hardt
 
JWT: jku x5u
JWT: jku x5uJWT: jku x5u
JWT: jku x5usnyff
 
Oracle APEX Performance
Oracle APEX PerformanceOracle APEX Performance
Oracle APEX PerformanceScott Wesley
 
Multi Client Development with Spring - Josh Long
Multi Client Development with Spring - Josh Long Multi Client Development with Spring - Josh Long
Multi Client Development with Spring - Josh Long jaxconf
 
A Cocktail of Guice and Seam, the missing ingredients for Java EE 6
A Cocktail of Guice and Seam, the missing ingredients for Java EE 6A Cocktail of Guice and Seam, the missing ingredients for Java EE 6
A Cocktail of Guice and Seam, the missing ingredients for Java EE 6Saltmarch Media
 
10 Ways to Gaurantee Your Azure Project will Fail
10 Ways to Gaurantee Your Azure Project will Fail10 Ways to Gaurantee Your Azure Project will Fail
10 Ways to Gaurantee Your Azure Project will FailMichael Collier
 

Semelhante a JDD2014: What you won't read in books about implementing REST services - Jakub Kubryński (20)

The vJUG talk about jOOQ: Get Back in Control of Your SQL
The vJUG talk about jOOQ: Get Back in Control of Your SQLThe vJUG talk about jOOQ: Get Back in Control of Your SQL
The vJUG talk about jOOQ: Get Back in Control of Your SQL
 
4Developers 2015: REST w praktyce - tej dobrej i tej złej - Jakub Kubryński
4Developers 2015: REST w praktyce - tej dobrej i tej złej - Jakub Kubryński4Developers 2015: REST w praktyce - tej dobrej i tej złej - Jakub Kubryński
4Developers 2015: REST w praktyce - tej dobrej i tej złej - Jakub Kubryński
 
Static Analysis in IDEA
Static Analysis in IDEAStatic Analysis in IDEA
Static Analysis in IDEA
 
Whatever it takes - Fixing SQLIA and XSS in the process
Whatever it takes - Fixing SQLIA and XSS in the processWhatever it takes - Fixing SQLIA and XSS in the process
Whatever it takes - Fixing SQLIA and XSS in the process
 
Keep your Wicket application in production
Keep your Wicket application in productionKeep your Wicket application in production
Keep your Wicket application in production
 
Get Back in Control of your SQL with jOOQ - GeekOut by ZeroTurnaround
Get Back in Control of your SQL with jOOQ - GeekOut by ZeroTurnaroundGet Back in Control of your SQL with jOOQ - GeekOut by ZeroTurnaround
Get Back in Control of your SQL with jOOQ - GeekOut by ZeroTurnaround
 
Solving anything in VCL
Solving anything in VCLSolving anything in VCL
Solving anything in VCL
 
Get Back in Control of your SQL
Get Back in Control of your SQLGet Back in Control of your SQL
Get Back in Control of your SQL
 
10 Excellent Ways to Secure Your Spring Boot Application - Devoxx Belgium 2019
10 Excellent Ways to Secure Your Spring Boot Application - Devoxx Belgium 201910 Excellent Ways to Secure Your Spring Boot Application - Devoxx Belgium 2019
10 Excellent Ways to Secure Your Spring Boot Application - Devoxx Belgium 2019
 
Bkbiet day2 & 3
Bkbiet day2 & 3Bkbiet day2 & 3
Bkbiet day2 & 3
 
Arquillian Constellation
Arquillian ConstellationArquillian Constellation
Arquillian Constellation
 
Spring 3: What's New
Spring 3: What's NewSpring 3: What's New
Spring 3: What's New
 
10 Excellent Ways to Secure Spring Boot Applications - Okta Webinar 2020
10 Excellent Ways to Secure Spring Boot Applications - Okta Webinar 202010 Excellent Ways to Secure Spring Boot Applications - Okta Webinar 2020
10 Excellent Ways to Secure Spring Boot Applications - Okta Webinar 2020
 
Testing the frontend
Testing the frontendTesting the frontend
Testing the frontend
 
JWT: jku x5u
JWT: jku x5uJWT: jku x5u
JWT: jku x5u
 
Vulpes tribes backend
Vulpes tribes backendVulpes tribes backend
Vulpes tribes backend
 
Oracle APEX Performance
Oracle APEX PerformanceOracle APEX Performance
Oracle APEX Performance
 
Multi Client Development with Spring - Josh Long
Multi Client Development with Spring - Josh Long Multi Client Development with Spring - Josh Long
Multi Client Development with Spring - Josh Long
 
A Cocktail of Guice and Seam, the missing ingredients for Java EE 6
A Cocktail of Guice and Seam, the missing ingredients for Java EE 6A Cocktail of Guice and Seam, the missing ingredients for Java EE 6
A Cocktail of Guice and Seam, the missing ingredients for Java EE 6
 
10 Ways to Gaurantee Your Azure Project will Fail
10 Ways to Gaurantee Your Azure Project will Fail10 Ways to Gaurantee Your Azure Project will Fail
10 Ways to Gaurantee Your Azure Project will Fail
 

Último

WSO2CON 2024 Slides - Open Source to SaaS
WSO2CON 2024 Slides - Open Source to SaaSWSO2CON 2024 Slides - Open Source to SaaS
WSO2CON 2024 Slides - Open Source to SaaSWSO2
 
WSO2Con204 - Hard Rock Presentation - Keynote
WSO2Con204 - Hard Rock Presentation - KeynoteWSO2Con204 - Hard Rock Presentation - Keynote
WSO2Con204 - Hard Rock Presentation - KeynoteWSO2
 
WSO2CON 2024 - How to Run a Security Program
WSO2CON 2024 - How to Run a Security ProgramWSO2CON 2024 - How to Run a Security Program
WSO2CON 2024 - How to Run a Security ProgramWSO2
 
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...WSO2
 
WSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
WSO2Con2024 - Enabling Transactional System's Exponential Growth With SimplicityWSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
WSO2Con2024 - Enabling Transactional System's Exponential Growth With SimplicityWSO2
 
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024VictoriaMetrics
 
WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?WSO2
 
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyviewmasabamasaba
 
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...Bert Jan Schrijver
 
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...masabamasaba
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfonteinmasabamasaba
 
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...WSO2
 
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...masabamasaba
 
WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...
WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...
WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...WSO2
 
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfonteinmasabamasaba
 
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...Jittipong Loespradit
 
tonesoftg
tonesoftgtonesoftg
tonesoftglanshi9
 
Architecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the pastArchitecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the pastPapp Krisztián
 
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...WSO2
 

Último (20)

WSO2CON 2024 Slides - Open Source to SaaS
WSO2CON 2024 Slides - Open Source to SaaSWSO2CON 2024 Slides - Open Source to SaaS
WSO2CON 2024 Slides - Open Source to SaaS
 
WSO2Con204 - Hard Rock Presentation - Keynote
WSO2Con204 - Hard Rock Presentation - KeynoteWSO2Con204 - Hard Rock Presentation - Keynote
WSO2Con204 - Hard Rock Presentation - Keynote
 
WSO2CON 2024 - How to Run a Security Program
WSO2CON 2024 - How to Run a Security ProgramWSO2CON 2024 - How to Run a Security Program
WSO2CON 2024 - How to Run a Security Program
 
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
 
WSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
WSO2Con2024 - Enabling Transactional System's Exponential Growth With SimplicityWSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
WSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
 
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
 
WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?
 
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
 
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
 
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
 
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
 
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
 
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
 
WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...
WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...
WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...
 
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
 
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
 
tonesoftg
tonesoftgtonesoftg
tonesoftg
 
Architecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the pastArchitecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the past
 
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
 

JDD2014: What you won't read in books about implementing REST services - Jakub Kubryński

  • 1. The thin line between RESTful and AWful Jakub Kubrynski jk@devskiller.com / @jkubrynski 1 / 48
  • 3. "The Code is more what you'd call guidelines than actual rules. Welcome aboard the Black Pearl, Miss Turner" -- Cpt. Hector Barbossa to Elizabeth Swann RT Ben Hale jk@devskiller.com / @jkubrynski 3 / 48
  • 4. Formal REST constraints Client-Server Stateless Cache Interface / Uniform Contract Layered System jk@devskiller.com / @jkubrynski 4 / 48
  • 5. Richardson maturity model http://martinfowler.com/articles/richardsonMaturityModel.html jk@devskiller.com / @jkubrynski 5 / 48
  • 6. POST vs PUT jk@devskiller.com / @jkubrynski 6 / 48
  • 7. POST vs PUT POST creates new resources jk@devskiller.com / @jkubrynski 7 / 48
  • 8. POST vs PUT POST creates new resources PUT updates existing resources PUT can create resource if ID is already known jk@devskiller.com / @jkubrynski 8 / 48
  • 9. Maybe PATCH? no "out of the box" support jk@devskiller.com / @jkubrynski 9 / 48
  • 10. Maybe PATCH? no "out of the box" support partial update @RequestMapping(value = "/{id}", method = PATCH) public void updateArticle(HttpServletRequest request, @PathVariable("id") String id) { Article currentArticle = repository.findOne(id); Article updatedArticle = objectMapper.readerForUpdating(currentArticle) .readValue(request.getReader()); repository.save(updatedArticle); } jk@devskiller.com / @jkubrynski 10 / 48
  • 11. Caching be aware - especially IE caches aggressively jk@devskiller.com / @jkubrynski 11 / 48
  • 12. Caching be aware - especially IE caches aggressively disable caching @Configuration public class RestConfig extends WebMvcConfigurerAdapter { @Override public void addInterceptors(InterceptorRegistry registry) { WebContentInterceptor webContentInterceptor = new WebContentInterceptor(); webContentInterceptor.setCacheSeconds(0); registry.addInterceptor(webContentInterceptor); } } jk@devskiller.com / @jkubrynski 12 / 48
  • 13. Cache headers cache-control: public, max-age=0, no-cache public / private no-cache no-store max-age s-maxage jk@devskiller.com / @jkubrynski 13 / 48
  • 14. Cache headers cache-control: public, max-age=0, no-cache public / private no-cache no-store max-age s-maxage ETag If-None-Match: "0d41d8cd98f00b204e9800998ecf8427e" Spring brings ShallowEtagHeaderFilter jk@devskiller.com / @jkubrynski 14 / 48
  • 15. Compression reduces response size dramatically in Tomcat extend Connector with compression="on" compressionMinSize="2048" noCompressionUserAgents="gozilla, traviata" compressableMimeType="text/html,text/xml" jk@devskiller.com / @jkubrynski 15 / 48
  • 16. HATEOAS self-descriptive client understands hypermedia { "name": "Alice", "links": [ { "rel": "self", "href": "/customers/1213" }, { "rel": "parent", "href": "/customers/14" }, { "rel": "currentOrder", "href": "/orders/14312" } ] } HTTP/1.1 201 Created Location: http://api.mydomain.com/orders/1234 jk@devskiller.com / @jkubrynski 16 / 48
  • 17. HATEOAS in Spring public class Customer extends ResourceSupport { ... } // or wrap entity into Resource object jk@devskiller.com / @jkubrynski 17 / 48
  • 18. HATEOAS in Spring public class Customer extends ResourceSupport { ... } // or wrap entity into Resource object import static org.springframework.hateoas.mvc.ControllerLinkBuilder.*; public HttpEntity<Customer> get(@PathVariable("id") String customerId) { Customer customer = repository.findOne(customerId); String pId = customer.getBoss(); String oId = customer.currentOrderId(); customer.add(linkTo(methodOn(CustomerController.class).get(customerId)).withSelfRel()); customer.add(linkTo(methodOn(CustomerController.class).get(pId)).withRel("parent")); customer.add(linkTo(methodOn(OrderController.class).get(oId)).withRel("currentOrder")); return new ResponseEntity<Customer>(customer, HttpStatus.OK); } public ResponseEntity create(@RequestBody Customer customer) { String id = repository.save(customer); return ResponseEntity.created(linkTo(CustomerController.class).slash(id).toUri()) .build(); } jk@devskiller.com / @jkubrynski 18 / 48
  • 19. @DanaDanger HTTP codes classification 20x: cool 30x: ask that dude over there 40x: you fucked up 50x: we fucked up jk@devskiller.com / @jkubrynski 19 / 48
  • 20. Exceptions include detailed information { "status": 400, "code": 40483, "message": "Incorrect body signature", "moreInfo": "http://www.mycompany.com/errors/40483" } jk@devskiller.com / @jkubrynski 20 / 48
  • 21. Exceptions include detailed information { "status": 400, "code": 40483, "message": "Incorrect body signature", "moreInfo": "http://www.mycompany.com/errors/40483" } hide stacktrace jk@devskiller.com / @jkubrynski 21 / 48
  • 22. Handling Spring MVC exceptions @ControllerAdvice public class MyExceptionHandler extends ResponseEntityExceptionHandler { /* Handling framework exceptions */ @Override protected ResponseEntity<Object> handleExceptionInternal(Exception ex, Object body, HttpHeaders headers, HttpStatus status, WebRequest request) { LOG.error("Spring MVC exception occurred", ex); return super.handleExceptionInternal(ex, body, headers, status, request); } /* Handling application exceptions */ @ResponseStatus(value = HttpStatus.NOT_FOUND) @ExceptionHandler(ResourceNotFoundException.class) public void handleResourceNotFound() { } } jk@devskiller.com / @jkubrynski 22 / 48
  • 23. API Versioning don't even think about api.domain.com/v2/orders URIs to the same resources should be fixed between versions jk@devskiller.com / @jkubrynski 23 / 48
  • 24. API Versioning don't even think about api.domain.com/v2/orders URIs to the same resources should be fixed between versions use Content-Type 1 version: application/vnd.domain+json 2 version: application/vnd.domain.v2+json jk@devskiller.com / @jkubrynski 24 / 48
  • 25. Filtering and sorting GET /reviews?rating=5 GET /reviews?rating=5&sortAsc=author jk@devskiller.com / @jkubrynski 25 / 48
  • 26. Filtering and sorting GET /reviews?rating=5 GET /reviews?rating=5&sortAsc=author Dynamic queries are easier in POST body jk@devskiller.com / @jkubrynski 26 / 48
  • 27. Filtering and sorting GET /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 27 / 48
  • 28. Documentation runnable with examples Swagger jk@devskiller.com / @jkubrynski 28 / 48
  • 30. Stateless or not? password hashing cost session replication load-balancing jk@devskiller.com / @jkubrynski 30 / 48
  • 31. Stateless or not? password hashing cost session replication load-balancing ... stateless session? jk@devskiller.com / @jkubrynski 31 / 48
  • 32. Avoiding session creation in Spring @EnableWebSecurity public class SpringSecurity extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .csrf().disable() .authorizeRequests() .antMatchers("/secure/**").fullyAuthenticated() .and() .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.NEVER) .and() .httpBasic(); } } jk@devskiller.com / @jkubrynski 32 / 48
  • 33. Security SQL Injection XSS CSRF XXE jk@devskiller.com / @jkubrynski 33 / 48
  • 34. HQL Injection List<Product> products = em.createQuery( "SELECT p FROM Product p where p.category = '" + categ + "'", Product.class) .getResultList(); jk@devskiller.com / @jkubrynski 34 / 48
  • 35. HQL Injection List<Product> products = em.createQuery( "SELECT p FROM Product p where p.category = '" + categ + "'", Product.class) .getResultList(); categ = ' OR '1'='1 jk@devskiller.com / @jkubrynski 35 / 48
  • 36. HQL Injection List<Product> products = em.createQuery( "SELECT p FROM Product p where p.category = '" + categ + "'", Product.class) .getResultList(); categ = ' OR '1'='1 SELECT __fields__ FROM products WHERE category = '' OR '1'='1' jk@devskiller.com / @jkubrynski 36 / 48
  • 37. HQL Injection List<Product> products = em.createQuery( "SELECT p FROM Product p where p.category = '" + categ + "'", Product.class) .getResultList(); categ = ' OR '1'='1 SELECT __fields__ FROM products WHERE category = '' OR '1'='1' List<Product> products = em.createQuery( "SELECT p FROM Product p where p.category = :categ", Product.class) .setParameter("categ", categ) .getResultList(); jk@devskiller.com / @jkubrynski 37 / 48
  • 38. HQL Injection List<Product> products = em.createQuery( "SELECT p FROM Product p where p.category = '" + categ + "'", Product.class) .getResultList(); categ = ' OR '1'='1 SELECT __fields__ FROM products WHERE category = '' OR '1'='1' List<Product> products = em.createQuery( "SELECT p FROM Product p where p.category = :categ", Product.class) .setParameter("categ", categ) .getResultList(); SELECT __fields__ FROM products WHERE category = ' OR ''1''=''1''' jk@devskiller.com / @jkubrynski 38 / 48
  • 39. 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 39 / 48
  • 40. 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 40 / 48
  • 41. CORS - Cross Origin Requests Sharing Preflight request OPTIONS /cors HTTP/1.1 Origin: http://www.domain.com Access-Control-Request-Method: PUT Access-Control-Request-Headers: X-Custom-Header Host: api.mydomain.org Accept-Language: en-US Connection: keep-alive User-Agent: Mozilla/5.0... Preflight response Access-Control-Allow-Origin: http://www.domain.com Access-Control-Allow-Methods: GET, POST, PUT Access-Control-Allow-Headers: X-Custom-Header Content-Type: text/html; charset=utf-8 jk@devskiller.com / @jkubrynski 41 / 48
  • 42. XML External Entity <?xml version="1.0" encoding="utf-8"?> <comment> <text>Yeah! I like it!</text> </comment> jk@devskiller.com / @jkubrynski 42 / 48
  • 43. 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 43 / 48
  • 44. 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 44 / 48
  • 45. 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 45 / 48
  • 46. 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 46 / 48
  • 47. http://knowyourmeme.com/photos/531557 thx to @mihn jk@devskiller.com / @jkubrynski 47 / 48
  • 48. Thanks! jk@devskiller.com / @jkubrynski 48 / 48