building a killer rest client for your rest json api
play

Building a Killer REST Client for Your REST+JSON API Les - PowerPoint PPT Presentation

Building a Killer REST Client for Your REST+JSON API Les Hazlewood @lhazlewood Apache Shiro Project Chair CTO, Stormpath stormpath.com @lhazlewood |


  1. Building ¡a ¡Killer ¡REST ¡Client ¡ for ¡Your ¡REST+JSON ¡API ¡ Les ¡Hazlewood ¡@lhazlewood ¡ Apache ¡Shiro ¡Project ¡Chair ¡ CTO, ¡Stormpath ¡stormpath.com ¡ @lhazlewood ¡| ¡@goStormpath ¡

  2. ¡ .com ¡ • User ¡Management ¡and ¡AuthenAcaAon ¡ API ¡ • Security ¡for ¡ your ¡applicaAons ¡ • User ¡security ¡workflows ¡ • Security ¡best ¡pracAces ¡ • Developer ¡tools, ¡SDKs, ¡libraries ¡ @lhazlewood ¡| ¡@goStormpath ¡

  3. Overview ¡ • Resources ¡ • Public ¡/ ¡Private ¡API ¡ • Proxy ¡Design ¡ • AcAve ¡Record ¡ • Fluent ¡API ¡ • ConfiguraAon ¡ • Caching ¡ • AuthenAcaAon ¡ • Pluggability ¡ • Lessons ¡Learned ¡ ¡ ¡ @lhazlewood ¡| ¡@goStormpath ¡

  4. HATEOAS ¡ • H ypermedia ¡ • A s ¡ • T he ¡ • E ngine ¡ • O f ¡ • A pplicaAon ¡ • S tate ¡ ¡ @lhazlewood ¡| ¡@goStormpath ¡

  5. Resources ¡ @lhazlewood ¡| ¡@goStormpath ¡

  6. Resources ¡ • Nouns, ¡not ¡verbs ¡ • Coarse-­‑grained, ¡not ¡fine-­‑grained ¡ • Support ¡many ¡use ¡cases ¡ • Globally ¡unique ¡HREF ¡ @lhazlewood ¡| ¡@goStormpath ¡

  7. CollecHon ¡Resource ¡ • Example: ¡ ¡ /applications � • First ¡class ¡resource ¡w/ ¡own ¡properAes: ¡ • offset � • limit � • items � • first, next, previous, last � • etc ¡ • items ¡contains ¡instance ¡resources ¡ @lhazlewood ¡| ¡@goStormpath ¡

  8. Instance ¡Resource ¡ • Example: ¡ /applications/8sZxUoExA30mP74 � � • Child ¡of ¡a ¡collecAon ¡ • RUD ¡(no ¡Create ¡-­‑ ¡done ¡via ¡parent ¡collecAon) ¡ @lhazlewood ¡| ¡@goStormpath ¡

  9. TranslaHng ¡to ¡Code ¡ @lhazlewood ¡| ¡@goStormpath ¡

  10. Resource ¡ public interface Resource { � String getHref(); � } � @lhazlewood ¡| ¡@goStormpath ¡

  11. Instance ¡Resource ¡ public interface Application � extends Resource, Saveable, Deleteable { � ... � } � � public interface Saveable { � void save(); � } � � public interface Deletable { � void delete(); � } � @lhazlewood ¡| ¡@goStormpath ¡

  12. CollecHon ¡Resource ¡ public interface � CollectionResource<T extends Resource> � extends Resource, Iterable<T> { � � int getOffset(); � � int getLimit(); � � } � @lhazlewood ¡| ¡@goStormpath ¡

  13. Example: ¡ApplicaHonList ¡ public interface ApplicationList � extends CollectionResource<Application> { � } � @lhazlewood ¡| ¡@goStormpath ¡

  14. Design! ¡ @lhazlewood ¡| ¡@goStormpath ¡

  15. EncapsulaHon ¡ • Public ¡API ¡ • Internal/Private ¡ImplementaAons ¡ • Extensions ¡ • Allows ¡for ¡change ¡w/ ¡minimal ¡impact ¡ hZp://semver.org ¡ @lhazlewood ¡| ¡@goStormpath ¡

  16. EncapsulaHon ¡in ¡pracHce ¡ project-root/ � |- api/ � | |- src/main/java � | � |- impl/ � | |- src/main/java � | � |- extendsions/ � | |- src/main/java � | � |- pom.xml � � @lhazlewood ¡| ¡@goStormpath ¡

  17. Public ¡API ¡ @lhazlewood ¡| ¡@goStormpath ¡

  18. Public ¡API ¡ • All ¡interfaces ¡ • Helper ¡classes ¡with ¡staAc ¡methods ¡ • Builder ¡interfaces ¡for ¡configuraAon ¡ ¡ • NO ¡IMPLEMENTATIONS ¡EXPOSED ¡ @lhazlewood ¡| ¡@goStormpath ¡

  19. Example ¡interfaces ¡ • Client ¡ • ClientBuilder ¡ • ApplicaAon ¡ • Directory ¡ • Account ¡ • Group ¡ • etc ¡ @lhazlewood ¡| ¡@goStormpath ¡

  20. Classes ¡with ¡staHc ¡helper ¡methods ¡ Client client = Clients .builder() � ... � .build(); � � • Create ¡mulAple ¡helper ¡classes ¡ separaAon ¡of ¡concerns ¡ @lhazlewood ¡| ¡@goStormpath ¡

  21. Builder ¡interfaces ¡for ¡configuraHon ¡ Client client = Clients. builder() .setApiKey( � ApiKeys. builder() .setFileLocation( � “$HOME/.stormpath/apiKey.properties”) � . build() ) � . build() ; � � Clients.builder() à ClientBuilder � ApiKeys.builder() à ApiKeyBuilder � � Single ¡Responsibility ¡Principle! ¡ ¡ @lhazlewood ¡| ¡@goStormpath ¡

  22. Private ¡API ¡ • ImplementaAons ¡+ ¡SPI ¡interfaces ¡ • Builder ¡implementaAons ¡ • ImplementaAon ¡Plugins ¡ ¡ @lhazlewood ¡| ¡@goStormpath ¡

  23. Resource ¡ImplementaHons ¡ • Create ¡a ¡base ¡AbstractResource ¡class: ¡ • Map ¡manipulaAon ¡methods ¡ • Dirty ¡checking ¡ • Reference ¡to ¡DataStore ¡ • Lazy ¡Loading ¡ • Locks ¡for ¡concurrent ¡access ¡ • Create ¡abstract ¡InstanceResource ¡and ¡CollecAonResource ¡ implementaAons ¡ • Extend ¡from ¡InstanceResource ¡or ¡CollecAonResource ¡ @lhazlewood ¡| ¡@goStormpath ¡

  24. Resource ¡ImplementaHons ¡ public class DefaultAccount extends InstanceResource � implements Account { � � @Override � public String getName() { � return (String)getProperty(“name”); � } � � @Override � public Account setName(String name) { � setProperty(“name”, name); � return this; � } � } � @lhazlewood ¡| ¡@goStormpath ¡

  25. Usage ¡Paradigm ¡ @lhazlewood ¡| ¡@goStormpath ¡

  26. Account ¡JSON ¡Resource ¡ { “href”: “https://api.stormpath.com/v1/accounts/x7y8z9”, “givenName”: “Tony”, “surname”: “Stark”, …, “directory”: { “href”: “https://api.stormpath.com/v1/directories/ g4h5i6” } } @lhazlewood ¡| ¡@goStormpath ¡

  27. Naïve ¡Design ¡(typesafe ¡language) ¡ //get account � String href = “https://api.stormpath.com/v1/....”; � Map<String,Object> account = � client.getResource(href); � � //get account’s parent directory via link: � Map<String,Object> dirLink = account.getDirectory(); � String dirHref = (String)dirLink.get(“href”); � � Map<String,Object> directory = � client.getResource(dirHref); � System.out.println(directory.get(“name”)); � � @lhazlewood ¡| ¡@goStormpath ¡

  28. Naïve ¡Design ¡(typesafe ¡language) ¡ • Results ¡in ¡*huge* ¡amount ¡of ¡Boilerplate ¡code ¡ • Not ¡good ¡ • Find ¡another ¡way ¡ @lhazlewood ¡| ¡@goStormpath ¡

  29. Proxy ¡PaUern ¡ String href = “https://api.stormpath.com/v1/....”; � Account account = client.getAccount(href); � � Directory directory = account.getDirectory(); � � System.out.println(directory.getName()); � � @lhazlewood ¡| ¡@goStormpath ¡

  30. Proxy ¡PaUern ¡ @lhazlewood ¡| ¡@goStormpath ¡

  31. Component ¡Design ¡ @lhazlewood ¡| ¡@goStormpath ¡

  32. Component ¡Architecture ¡ account ¡ .save() ¡ @lhazlewood ¡| ¡@goStormpath ¡

  33. Component ¡Architecture ¡ account ¡ .save() ¡ DataStore ¡ @lhazlewood ¡| ¡@goStormpath ¡

  34. Component ¡Architecture ¡ account ¡ .save() ¡ DataStore ¡ MapMarshaller ¡ ¡ ¡ ¡ JSON ¡<-­‑-­‑> ¡Map ¡ @lhazlewood ¡| ¡@goStormpath ¡

  35. Component ¡Architecture ¡ account ¡ .save() ¡ DataStore ¡ MapMarshaller ¡ ResourceFactory ¡ ¡ ¡ ¡ JSON ¡<-­‑-­‑> ¡Map ¡ ¡ ¡ ¡ Map ¡ à ¡Resource ¡ @lhazlewood ¡| ¡@goStormpath ¡

  36. Component ¡Architecture ¡ account ¡ .save() ¡ DataStore ¡ MapMarshaller ¡ ResourceFactory ¡ Cache ¡ ¡ ¡ ¡ JSON ¡<-­‑-­‑> ¡Map ¡ ¡ ¡ ¡ Map ¡ à ¡Resource ¡ Manager ¡ @lhazlewood ¡| ¡@goStormpath ¡

  37. Component ¡Architecture ¡ account ¡ .save() ¡ DataStore ¡ MapMarshaller ¡ ResourceFactory ¡ Cache ¡ ¡ ¡ ¡ JSON ¡<-­‑-­‑> ¡Map ¡ ¡ ¡ ¡ Map ¡ à ¡Resource ¡ Manager ¡ RequestExecutor ¡ @lhazlewood ¡| ¡@goStormpath ¡

  38. Component ¡Architecture ¡ account ¡ .save() ¡ DataStore ¡ MapMarshaller ¡ ResourceFactory ¡ Cache ¡ ¡ ¡ ¡ JSON ¡<-­‑-­‑> ¡Map ¡ ¡ ¡ ¡ Map ¡ à ¡Resource ¡ Manager ¡ AuthenAcaAon RequestExecutor ¡ Strategy ¡ Request ¡ AuthenAcator ¡ @lhazlewood ¡| ¡@goStormpath ¡

  39. Component ¡Architecture ¡ account ¡ .save() ¡ DataStore ¡ MapMarshaller ¡ ResourceFactory ¡ Cache ¡ ¡ ¡ ¡ JSON ¡<-­‑-­‑> ¡Map ¡ ¡ ¡ ¡ Map ¡ à ¡Resource ¡ Manager ¡ AuthenAcaAon RequestExecutor ¡ Strategy ¡ Request ¡ AuthenAcator ¡ API ¡Server ¡ @lhazlewood ¡| ¡@goStormpath ¡

  40. Caching ¡ @lhazlewood ¡| ¡@goStormpath ¡

Recommend


More recommend