scalabay - api design antipatterns

Post on 19-Oct-2014

243 Views

Category:

Technology

2 Downloads

Preview:

Click to see full reader

DESCRIPTION

Slides from my talk on API Design Patterns at ScalaBay Meetup at Netflix on 09/09/2014. http://www.meetup.com/Scala-Bay/events/195982742/

TRANSCRIPT

API  An&pa)erns  …iden&fying,  and  avoiding  them  

 

Manish Pandit @lobster1234

 Manish  Pandit  @lobster1234  

mpandit  at  neAlix  dot  com    

linkedin.com/in/mpandit  slideshare.net/lobster1234  

@lobster1234

APIs  

   

A  means  for  soGware  to  interact  with  other  soGware.  

@lobster1234

   

@lobster1234

@lobster1234

Image  Credit:  h)p://en.wikipedia.org/wiki/Internet_of_Things  

@lobster1234

REST  API  

REST  is  not  a  standard,  but  an  architecture    

@lobster1234

REST  API  

REST  is  not  a  standard,  but  an  architecture,  which  uses  HTTP  as  a  model  for  all  interac.ons.  

 If  HTTP  is  a  standard,  REST  is  a  conven&on.  

@lobster1234

@lobster1234

REST  API  

 Noun  è  Resource,  or  the  En&ty  

 Verb  è  Ac&on  

+  Iden.fier    

@lobster1234

Image:  h)p://www.educa&on.com/study-­‐help/ar&cle/nouns/    

@lobster1234

Protocol  

   

May  or  may  not  be  standard  

@lobster1234

Protocol  

     

May  or  may  not  be  standard  Indicates  an  agreement  between  the  par&es  

   

@lobster1234

@lobster1234

Payload  

     

Format  (XML,  JSON,  Custom  Text,  Binary..)    

Transport  (HTTP,  Binary  over  sockets,  FTP..)  

@lobster1234

   

@lobster1234

   h)p://www.neAlix.com/header/neAlix_logo.gif    Or,  reques.ng  a  resource  from  the  server  by  

giving  its  path  using  a  protocol.  

@lobster1234

Every  request  deserves  a  response.  

@lobster1234

Headers  describe  the  response  

@lobster1234

Headers  describe  the  response    

Status  Code  indicates  the  success/failure  

@lobster1234

 Headers  describe  the  response  

 Status  Code  indicates  the  success/failure  

 Body  contains  the  actual  payload  

@lobster1234

   

Tell  the  server  what  to  do  via  ac.ons  

@lobster1234

   Ac&ons  are  HTTP  methods,  which  map  nicely  to  

(most  of)  the  business  interac&ons  

@lobster1234

 Create  –  POST  Read  –  GET  

Update  –  PUT  (or  PATCH)  Delete  -­‐  DELETE  

 HEAD,  OPTIONS,  TRACE,  CONNECT  

@lobster1234

Pa)erns  

@lobster1234

Pa)erns  

Pa)erns  are  re-­‐usable  solu&ons  to  commonly  occurring  problems.  

@lobster1234

Common  Scenarios  

   

Gebng  data  from  the  server      

@lobster1234

Common  Scenarios  

   

Gebng  data  from  the  server    

Sending  data  to  the  server    

@lobster1234

An&pa)erns  

     

An&pa)erns  are  re-­‐usable  solu&ons  to    commonly  occurring  problems,  that  look  great  on  the  surface,  but  

really  aren’t.  

 

@lobster1234

   

Request  An&pa)erns  

@lobster1234

   

Over-­‐using  Query  Strings  

@lobster1234

   

/pets?name=scruffy  vs.  

/pets/name/scruffy  

@lobster1234

   

/pets?name=scruffy&zip=94568  vs.  

/pets/name/scruffy/loca&on/zip/94568  

@lobster1234

     

Avoid  query  strings  for  resource  iden&fica&on  But  use  them  for  request  metadata  *  

   

*Except  for  search  

@lobster1234

   

Pagina&on  Filtering  Sor&ng  

..  

@lobster1234

@lobster1234

Query  Strings  

 h)p://some.api.com/movies?start=0&count=10&sortBy=name&fields=name,cast,releaseDate  

@lobster1234

   

Allowing  clients  to  scrape  the  data  via  your  APIs  

@lobster1234

@lobster1234

   

Think  batch  jobs  reques&ng  the  catalog  nightly!  

@lobster1234

   

Request  metadata  to  the  rescue?  

@lobster1234

     

….how  about  a  ?since=1d    

…or  ?since=UTC  

@lobster1234

   

Method  An&pa)erns  

@lobster1234

   

Using  Query  Strings  to  overload  verbs  

@lobster1234

     

/pets?perform=update&name=scruffy&id=24  

@lobster1234

     

Use  the  appropriate  HTTP  Method  to  represent  your  ac&on  

 

@lobster1234

   

Using  POST  for  all  writes  

@lobster1234

     

GET  to  retrieve,  or  search  POST  to  create,  or  upsert  

PUT  to  update  (or  be)er  yet,  PATCH)  DELETE  to  delete  

@lobster1234

   Using  HTTP  PUT  or  POST  to  set  a  value  to  null  

@lobster1234

Updates  vs.  Deletes  

 Everything  works  when  there  is  data,  but  what  

when  there  is  no  data..?  

@lobster1234

   

 Use  HTTP  DELETE  to  set  a  value  to  null  

 Remember,  we  have  a  path  to  not  just  the  resource,  but  also  it’s  

a)ributes  

@lobster1234

   

 DELETE  /pets/<id>/collartag  

   

@lobster1234

   

Response  An&pa)erns  

@lobster1234

   

Always  returning  HTTP  200  

@lobster1234

@lobster1234

HTTP  200  OK    

{  “success”  :  false  }  

@lobster1234

HTTP  200  OK    

{  “error”  :  ”Person  jdoe  not  found”  }  

@lobster1234

 

 

2xx  for  success  3xx  for  redirects/caching  

4xx  for  request/client  errors  5xx  for  server  errors  

@lobster1234

Some  Useful  (and  not  so  common)  Codes    

Return  aGer  a  delete  -­‐  204  Failed  database  constraint  -­‐  409  Method  not  supported  -­‐  405  

Trying  to  ask  for  too  much  data  -­‐  413  Valida&on  Failure  -­‐  418  

@lobster1234

 Always  returning  a  401  for  auth  failures  

   

@lobster1234

Auth  

     

Use  HTTP  401  Unauthorized  to  indicate  that  the  client  needs  to  authen&cate  

@lobster1234

Auth  

     

Use  HTTP  403  Forbidden  to  indicate  that  the  client’s  creden&als  do  not  allow  access  to  the  

requested  resource  

@lobster1234

401  vs  403  

   

401  =  Come  back  with  a  key    

403  =  Your  key  does  not  work  for  this  lock.  

@lobster1234

 Processing  requests  synchronously,  even  &me  

intensive  ones    

@lobster1234

     

Async  the  opera&on,  and  return    HTTP  202  –  Accepted  

   

@lobster1234

@lobster1234

 Async  opera&on’s  response  should  help  the  

caller.    

{“statusUrl”:  <some  URL>}  

@lobster1234

   

Organiza&onal  An&pa)erns  

@lobster1234

   

Not  differen&a&ng  between  en..es  and  instances  

 

@lobster1234

   

/pets?type=dog&name=big    vs    

/pets/dogs/name/big  

@lobster1234

     

Namespace  your  resources  in  a  collec&on  Use  paths  and  iden&fiers  to  traverse  

   

@lobster1234

   

Using  id  in  the  resource  iden&fica&on  path    

@lobster1234

 /pets/id/1234  

 vs    

/pets/1234  

@lobster1234

   

 Use  all  other  a)ributes  in  the  path,  except  the  

id.    id  is  implied  

@lobster1234

 

@lobster1234

Resources  in  an  island  

@lobster1234

 Every  en&ty  or  a  resource  is  &ed  to  others.  

 

@lobster1234

 Every  en&ty  or  a  resource  is  &ed  to  others.  

 And  you’re  stuck  guessing  the  connec&ons!  

@lobster1234

 

@lobster1234

We’ll  just  return  the  IDs!  

 HATEOAS  

(or  something  similar)  

@lobster1234

 Read  code  to  figure  out  the  resources  and  

a)ributes.            

@lobster1234

@lobster1234

     

Use  Meta  pages  for  resource  descrip&on  /resource/meta  /collec&on/meta  

@lobster1234

 APIs  are  not  discoverable  

         

@lobster1234

     

Consider  a  documenta&on  generator  like  Swagger,  IODocs  

@lobster1234

 Relying  on  cookies  for  authen&ca&on  

@lobster1234

@lobster1234

 Accept  cookies  as  a  fallback,  but  prefer  a  query  

parameter  or  HTTP  request  header.    

@lobster1234

 Storing  state  on  the  server  nodes  

@lobster1234

   

Stateless  ==  Simple  

@lobster1234

   

Requests  either  modify  the  state  of  a  resource,  or  read  it.    

All  requests  to  the  cluster  see  the  same  state  of  the  resource  

 

@lobster1234

     

Avoid  state  as  much  as  possible.  Maintain  the  state  in  the  database.  

If  you  need  to  store  transient  state  on  the  server,  it’s  a  code  (or  architecture)  smell.  

@lobster1234

Versioning  Using  301s  to  redirect/re&re  APIs  

 Caching  

Using  HTTP  headers  correctly  Caching  response  bodies  

@lobster1234

@lobster1234

Fin  

top related