Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Designing Web APIs

Pedro Felix
December 02, 2015

Designing Web APIs

Session presented at the Microsoft Web Camp, Lisbon, December 2015.
Video available (in Portuguese) at https://channel9.msdn.com/Events/DXPortugal/Microsoft-WebCamp-2015/ASP06

Pedro Felix

December 02, 2015
Tweet

More Decks by Pedro Felix

Other Decks in Programming

Transcript

  1. whoami • Teacher at the Lisbon Polytechnic Institute - ISEL

    • Software developer and consultant • Telecommunication and media industries • Focus on Web APIs, Identity and Access Management • Designing Evolvable Web APIs with ASP.NET, O’Reilly, 2014 See http://webapibook.net/ 3
  2. Outline • Designing evolvable APIs for the Web • Application

    Programming Interfaces • Able to evolve over time • Taking advantage of the Web architecture and technologies • Using ASP.NET 5 and MVC 6 4
  3. Time matters "REST is software engineering on the scale of

    DECADES" R. Fielding http://www.slideshare.net/evolve_conference/201308-fielding-evolve/31 8
  4. Once upon a time … • 1996 – ASP •

    2002 – ASP.NET • 2006 – WCF • 2008 – ASP.NET MVC • 2009 – WCF REST Starter KIT • 2012 – ASP.NET Web API, OWIN - Open Web Server Interface for .NET • 2013 – Katana 2.0, MVC 5 and Web API 2 • MVC 5 and Web API 2 – two different code bases with similar models • ASP.NET based on a 12 year old model • Practically impossible to make it cross-platform • 2014..2016 – ASP.NET 5 and MVC 6 9
  5. ASP.NET 5 • Renewed architecture - no more System.Web •

    Based on and compatible with OWIN • Modular • Isolation and side-by-side execution • Cross-platform - CoreCLR • Based on a new execution model • New hosting model: self-hosting (Kestrel) + reverse proxy (IIS, nginx) 10
  6. Middle Ware Middle Ware MVC ControllerClass HTTP Request Message HTTP

    Response Message ReturnType ActionMtd(PrmType p1, ...) Domain Middle Ware Action Filters Binding Input Formatters Output Formatters
  7. Representation Design • There is always a contract – make

    it explicit • Do not use serialized internal objects as representations • Representation-first design • If using serialization, create representation model classes • Be conservative – if field not needed, do not include it • Design for evolution – if field needed, make it extensible • Be consistent – create a field glossary 14
  8. Representation Design • Beware of the “JSON blank canvas” effect

    • Use purpose specific media-types where applicable • application/calendar+json • application/problem+json • application/pdf • Use general purpose hypermedia enabled types • application/hal+json • application/vnd.siren+json 15
  9. Why hypermedia? { “name” : “Pedro”, “imageId” : 123 }

    GET https://www.example.net/images/123 16
  10. Why common formats? { “name” : “Pedro”, “_links” : {

    “d:image”:{“href”:“https://some.cdn.com/images/123”} } } GET https://some.cdn.com/images/123 19
  11. Why common formats? { “name” : “Pedro”, “_links” : {

    “d:image”:{“href”:“https://some.cdn.com/images/123”} } } GET https://some.cdn.com/images/123 20 An intermediary that understand these can make a prefetch
  12. Why URI templates? { “name” : “Pedro”, “_links” : {

    “d:image”:{“href”:“https://some.cdn.com/images/123”} } } GET https://some.cdn.com/images/123?h=100&w=300 21
  13. Why URI templates? - RFC 6570 { “name” : “Pedro”,

    “_links” : { “d:image”:{“href”:“https://some.cdn.com/images/123{?h,w}”} } } GET https://some.cdn.com/images/123?h=100&w=300 22
  14. Why URI templates? - RFC 6570 { “name” : “Pedro”,

    “_links” : { “d:image”:{“href”:“https://some.cdn.com/images/123{/h,w}”} } } GET https://some.cdn.com/images/123/100/300 23
  15. Why hypermedia? { “name” : “Pedro”, “_links” : { “d:image”:{“href”:“https://some.cdn.com/images/123{/h,w}”}

    “d:github”:{“href”:“https://api.github.com/users/pmhsfelix”} } } GET https://api.github.com/users/pmhsfelix 24
  16. https://api.github.com/users/pmhsfelix { "login": "pmhsfelix", "avatar_url": "https://avatars.githubusercontent.com/u/364600?v=3", "url": "https://api.github.com/users/pmhsfelix", "html_url": "https://github.com/pmhsfelix",

    "gists_url": "https://api.github.com/users/pmhsfelix/gists{/gist_id}", "starred_url": "https://api.github.com/users/pmhsfelix/starred{/owner}{/repo}", "type": "User", "name": "Pedro Felix", "location": "Lisbon", 25
  17. Some hypermedia usages • Relation between resources • E.g. Where

    is next page on the collection? • E.g. Where are the comments for the current issue • Embed external resources • E.g. Break a representation into multiple parts • Workflow • E.g. How can I search this collection? • E.g. How to add an element to the collection? • Access control (hinting, not enforcement) • E.g. Can I edit the represented resource? Suggestion: http://vimeo.com/49484938 26
  18. HAL - Hypermedia Application Language { "_links": { "self": {

    "href": "/api/issues/123"}, "author" : {"href”: “/api/users/pmhsfelix"} }, "title": “MS Web Camp", "description": "Create slides for the MS Web Camp session", "_embedded": { "issues:comments": [ { "_links": { "self": {"href" : "/api/issues/123/comment/1"}}, "text": "don’t forget it’s only 40 minutes" },{ "_links": { "self": {"href" : "/api/issues/123/comment/2"}}, "text": "finally done" } ] }} 27
  19. HAL - Hypermedia Application Language { "_links": { "self": {

    "href": "/api/issues/123"}, "author" : {"href”: “/api/users/pmhsfelix"} }, "title": “MS Web Camp", "description": "Create slides for the MS Web Camp session", "_embedded": { "issues:comments": [ { "_links": { "self": {"href" : "/api/issues/123/comment/1"}}, "text": "don’t forget it’s only 40 minutes" },{ "_links": { "self": {"href" : "/api/issues/123/comment/2"}}, "text": "finally done" } ] }} 28
  20. HAL - Hypermedia Application Language { "_links": { "self": {

    "href": "/api/issues/123"}, "author" : {"href”: “/api/users/pmhsfelix"} }, "title": “MS Web Camp", "description": "Create slides for the MS Web Camp session", "_embedded": { "issues:comments": [ { "_links": { "self": {"href" : "/api/issues/123/comment/1"}}, "text": "don’t forget it’s only 40 minutes" },{ "_links": { "self": {"href" : "/api/issues/123/comment/2"}}, "text": "finally done" } ] }} 29
  21. Evolving an API • What endpoints to add? • What

    information to add to representations? • Data - fields • Control - links • New representation formats and content negotiation 31
  22. Evolving an API • What endpoints to add? • What

    information to add to representations? • Data - fields • Control - links • New representation formats and content negotiation • Adding new links may require new targets (aka “endpoints”) • However that is a consequence • And a server side concern 32
  23. Representing non-success • Use HTTP status codes to classify request

    outcomes • Success comes in multiple flavours – 200, 201, 202, 304, ... • Do not use a 2xx for a non-success outcome • Differentiate between 4xx and 5xx • Avoid “overly creative” interpretations of HTTP status codes • Non-success also deserves well-designed representations • “Problem Details for HTTP APIs”, https://tools.ietf.org/html/draft-ietf-appsawg-http-problem-01 35
  24. application/problem+json HTTP/1.1 403 Forbidden Content-Type: application/problem+json Content-Language: en { "type":

    "https://example.com/probs/out-of-credit", "title": "You do not have enough credit.", "detail": "Your current balance is 30, but that costs 50.", "instance": "/account/12345/msgs/abc", "balance": 30, "accounts": ["/account/12345", "/account/67890"] } 36 Adapted from https://tools.ietf.org/html/draft-ietf-appsawg-http-problem-01
  25. application/problem+json HTTP/1.1 403 Forbidden Content-Type: application/problem+json Content-Language: en { "type":

    "https://example.com/probs/out-of-credit", "title": "You do not have enough credit.", "detail": "Your current balance is 30, but that costs 50.", "instance": "/account/12345/msgs/abc", "balance": 30, "accounts": ["/account/12345", "/account/67890"] } 37
  26. application/problem+json HTTP/1.1 403 Forbidden Content-Type: application/problem+json Content-Language: en { "type":

    "https://example.com/probs/out-of-credit", "title": "You do not have enough credit.", "detail": "Your current balance is 30, but that costs 50.", "instance": "/account/12345/msgs/abc", "balance": 30, "accounts": ["/account/12345", "/account/67890"] } 38
  27. Identity and access management • Use explicit token based authentication

    and authorization • Avoid cookies – CSRF • Use the Authorization header • Avoid secrets in the URL or custom headers • Use the Two-party requester model: user + client application • Distinct client ID per client type and version • Helps feature usage visibility and breaking changes • Apply transversally - e.g. logging 39
  28. Identity and access management • Use OAuth 2.0 flows to

    provide tokens to client apps • Client Credential Flow – Server to Server • Authorization Code Grant – Client to Server • Resource Owner Password Credentials Grant – Client to Server • No browser user-agent available • Use OpenID Connect to authenticate with external IdPs • And no, OAuth 2.0 isn’t an authentication protocol 40
  29. Identity and access management • Use JwtBearerMiddleware to extract and

    validate generic JWT • Use IdentityServer3 for token generation • https://github.com/IdentityServer/IdentityServer3 • Authorization Server - token issuer • Federation Gateway - interface with external IdPs • Hostable on ASP.NET 5 with full .NET framework (no CoreCLR support yet) • IdentityServer3.AccessTokenValidation.Integration.AspNet Nuget • Reference token validation 41
  30. Final remarks • “Use the Source, Luke” - https://github.com/aspnet •

    Take advantage of DNX source based dependency resolution • Middleware + Filters + Binders/Formatters + Controllers + Actions • Focus on hypermedia representation design and evolution • Errors deserve well crafted representations too • Token based access control and the two-party model • https://github.com/pmhsfelix/AspNet5Mvc6FactsAndSamples • http://nordicapis.com/designing-evolvable-apis-web-interaction 42
  31. API documentation • Using definition languages such as Swagger Description

    Model API Framework plugin Description first Docs & client UI 44
  32. API documentation • Rather easy to set up • Client

    UI is an important feature • Experimentation purposes • RPC mindset – emphasis on the “endpoints” • List of operations and parameters • Operation result schema and status codes • Not hypermedia aware • Alternative: HAL browser – https://api.foxycart.com/hal-browser/browser.html#/ • Not a substitute for human-crafted transversal documentation 45