Successfully reported this slideshow.
Your SlideShare is downloading. ×

Building Next-Generation Web APIs with JSON-LD and Hydra

More Related Content

Related Books

Free with a 30 day trial from Scribd

See all

Building Next-Generation Web APIs with JSON-LD and Hydra

  1. 1. Building Next-Gen Web APIs with JSON-LD and Hydra Markus Lanthaler
  2. 2. Why do we need a website? Of course we have a website Why do we need an API? 1995 2000 2005 2010 Of course we have an API Adapted from T. Vitvar’s and J. Musser’s ECOWS 2010 Keynote, “ProgrammableWeb.com:Statistics, Trends, and Best Practices”
  3. 3. Using Web APIs is still challenging
  4. 4. Level 0:The Swamp of POX Level 1: Resources Level 2: HTTPVerbs
  5. 5. { "id": "cso29ax", "title": "Symfony Live Portland 2013", "description": "Prepare slides", "is_open": true, "created_at": "2012-11-26T04:49:44Z" } http://example.com/issues/cso29ax
  6. 6. BILLION DOLLAR QUESTION the
  7. 7. { "id": "cso29ax", "title": "Symfony Live Portland 2013", "description": "Prepare slides", "is_open": true, "created_at": "2012-11-26T04:49:44Z" } http://example.com/issues/cso29ax http://example.com/issue/{id}/comments/
  8. 8. { "id": "cso29ax", "title": "Symfony Live Portland 2013", "description": "Prepare slides", "is_open": true, "created_at": "2012-11-26T04:49:44Z", "comments": "/issues/cso29ax/comments/" } http://example.com/issues/cso29ax
  9. 9. Level 0:The Swamp of POX Level 1: Resources Level 2: HTTPVerbs Level 3: Hypermedia Controls
  10. 10. { "id": "cso29ax", "title": "Symfony Live Portland 2013", "description": "Prepare slides", "is_open": true, "created_at": "2012-11-26T04:49:44Z", "comments": "/issues/cso29ax/comments/" } http://example.com/issues/cso29ax
  11. 11. Every API is a snowflake
  12. 12. Result: tightly coupled & brittle systems
  13. 13. { "id": "cso29ax", "title": "Symfony Live Portland 2013", "description": "Prepare slides", "is_open": true, "created_at": "2012-11-26T04:49:44Z", "comments": "/issues/cso29ax/comments/" } http://example.com/issues/cso29ax
  14. 14. { 69 64: 63 73 6f 32 39 61 78 74 69 74 6c 65: 53 79 6d 66 6f 6e 79 20 4c 69 76 … 64 65 73 63 72 69 70 74 69 6f 6e: 50 72 65 70 61 … 69 73 5f 6f 70 65 6e: 01 63 72 65 61 74 65 64 5f 61 74: 32 30 31 32 2d 31 … 63 6f 6d 6d 65 6e 74 73: 2f 69 73 73 75 65 73 2f … } http://example.com/issues/cso29ax
  15. 15. Identifiers on the Web: URIs
  16. 16. Linked Data Principles Tim Berners-Lee, 2006
  17. 17. JSON-LD
  18. 18. Make data self-descriptive by mapping concepts to URLs
  19. 19. { "id": "markus", "firstname": "Markus", "lastname": "Lanthaler", "homepage": "http://www.markus-lanthaler.com/" }
  20. 20. { "@context": { "firstname": "http://schema.org/givenName", "lastname": "http://schema.org/familyName", "homepage": "http://schema.org/url" }, "id": "markus", "firstname": "Markus", "lastname": "Lanthaler", "homepage": "http://www.markus-lanthaler.com/" }
  21. 21. { "@context": { "firstname": "http://schema.org/givenName", "lastname": "http://schema.org/familyName", "homepage": "http://schema.org/url" }, "@id": "/people/markus", "firstname": "Markus", "lastname": "Lanthaler", "homepage": "http://www.markus-lanthaler.com/" }
  22. 22. { "@context": { "firstname": "http://schema.org/givenName", "lastname": "http://schema.org/familyName", "homepage": "http://schema.org/url" }, "@id": "/people/markus", "firstname": "Markus", "lastname": "Lanthaler", "homepage": "http://www.markus-lanthaler.com/" }
  23. 23. { "@context": { "firstname": "http://schema.org/givenName", "lastname": "http://schema.org/familyName", "homepage": "http://schema.org/url" }, "@id": "/people/markus", "firstname": "Markus", "lastname": "Lanthaler", "homepage": { "@id": "http://www.markus-lanthaler.com/" } }
  24. 24. { "@context": { "firstname": "http://schema.org/givenName", "lastname": "http://schema.org/familyName", "homepage": { "@id": "http://schema.org/url", "@type": "@id" }, }, "@id": "/people/markus", "firstname": "Markus", "lastname": "Lanthaler", "homepage": "http://www.markus-lanthaler.com/" }
  25. 25. { "@context": { "firstname": "http://schema.org/givenName", "lastname": "http://schema.org/familyName", "homepage": { "@id": "http://schema.org/url", "@type": "@id" } }, "@id": "/people/markus", "@type": "http://schema.org/Person", "firstname": "Markus", "lastname": "Lanthaler", "homepage": "http://www.markus-lanthaler.com/" }
  26. 26. { "@context": { "firstname": "http://schema.org/givenName", "lastname": "http://schema.org/familyName", "homepage": { "@id": "http://schema.org/url", "@type": "@id" } }, "@id": "/people/markus", "@type": "http://schema.org/Person", "firstname": "Markus", "lastname": "Lanthaler", "homepage": "http://www.markus-lanthaler.com/" }
  27. 27. { "@context": "/contexts/person.jsonld", "@id": "/people/markus", "@type": "http://schema.org/Person", "firstname": "Markus", "lastname": "Lanthaler", "homepage": "http://www.markus-lanthaler.com/" }
  28. 28. CMF
  29. 29. { "id": "cso29ax", "title": "Symfony Live Portland 2013", "description": "Prepare slides", "is_open": true, "created_at": "2012-11-26T04:49:44Z", "comments": "/issues/cso29ax/comments/" } http://example.com/issues/cso29ax
  30. 30. { "@context": "/ctx/context.jsonld", "id": "cso29ax", "title": "Symfony Live Portland 2013", "description": "Prepare slides", "is_open": true, "created_at": "2012-11-26T04:49:44Z", "comments": "/issues/cso29ax/comments/" } http://example.com/issues/cso29ax
  31. 31. { "@context": "/ctx/context.jsonld", "id": "cso29ax", "title": "Symfony Live Portland 2013", "description": "Prepare slides", "is_open": true, "created_at": "2012-11-26T04:49:44Z", "comments": "/issues/cso29ax/comments/" } http://example.com/issues/cso29ax
  32. 32. { "@id": "#comments", "@type": "hydra:Link", "supportedOperations": [ { "@id": "#create-comment", "@type": "hydra:CreateResourceOperation", "label": "Creates a new comment", "method": "POST", "expects": "#Comment", "returns": "#Comment" } ] } http://example.com/api/doc
  33. 33. { "@id": "#Comment", "@type": "hydra:Class", "supportedProperties": [ { "property": "#text", "required": true, "readonly": false, "writeonly": false } ] } http://example.com/api/doc
  34. 34. /** * An Issue tracked by the system. * * @HydraExpose() */ class Issue { /** * The comments associated with this issue * * @HydraExpose() * @HydraCollection("issue_comments") * @HydraOperations("issue_comment_create") */ private $comments; // ... other members and methods ... }
  35. 35. $ php app/console hydra:generate:crud --entity=MLDemoBundle:Issue --route-prefix=/issues/ --with-write --no-interaction CRUD generation Generating the CRUD code: OK You can now start using the generated code!
  36. 36. /** * Issue controller * * @Route("/issues") */ class IssueController extends HydraController { /** * Creates a new Issue * * @Route("/", name="issue_create") * @Method("POST") * * @HydraOperation(expect = "MLDemoBundleEntityIssue") * * @return MLDemoBundleEntityIssue */ public function collectionPostAction(Request $request) { ...
  37. 37. Hydra Console
  38. 38. © 2013, Markus Lanthaler. Some Rights Reserved. http://creativecommons.org/licenses/by-nc-sa/3.0/ Thank You
  39. 39. Questions? Markus Lanthaler http://www.markus-lanthaler.com @MarkusLanthaler mail@markus-lanthaler.com
  40. 40. Image Credits (1) http://www.flickr.com/photos/justinwkern/3729649672/ (2) http://www.flickr.com/photos/alexdram/3095419858/ (3) http://www.flickr.com/photos/kaptainkobold/3203311346/ (11) http://info.cern.ch/hypertext/WWW/TheProject.html (15) Adapted from http://www.flickr.com/photos/nebarnix/361650027/ (16) http://www.flickr.com/photos/joyoflife/1570126182/ (19) http://www.flickr.com/photos/rossiprojects/5592552858/ (21) http://www.flickr.com/photos/rossiprojects/5592552858/ (23) http://www.flickr.com/photos/clevercupcakes/4397152402/ (31) http://schema.org/Person (36) http://www.vonwong.com/ (42) http://www.flickr.com/photos/jakecaptive/3205277810/ (47) http://www.flickr.com/photos/sis/126152933/

×