$30 off During Our Annual Pro Sale. View Details »

Creating Solid APIs - DjangoCon AU 2018

Rivo Laks
August 23, 2018

Creating Solid APIs - DjangoCon AU 2018

Presented at DjangoCon AU 2018

Creating APIs that other developers love to use isn't trivial. I'll share some tips and best practices.

See also: https://rivolaks.com/posts/creating-solid-apis/

Rivo Laks

August 23, 2018
Tweet

More Decks by Rivo Laks

Other Decks in Programming

Transcript

  1. Creating Solid APIs
    DjangoCon AU 2018
    Rivo Laks ⋅ 2018-08-24

    View Slide

  2. Background

    View Slide

  3. What is an API?

    View Slide

  4. What is an API?
    application programming interface

    View Slide

  5. What is an API?
    application programming interface
    application programmer interface

    View Slide

  6. What is an API?
    application programming interface
    application programmer interface
    API is user interface for developers

    View Slide

  7. Goals

    View Slide

  8. Goals

    View Slide

  9. Goals
    Comprehensive API for 3rd-party devs

    View Slide

  10. Goals
    Comprehensive API for 3rd-party devs
    Easy & automated onboarding

    View Slide

  11. Goals
    Comprehensive API for 3rd-party devs
    Easy & automated onboarding
    Minimize pain (friction)

    View Slide

  12. Versioning

    View Slide

  13. Why Do We Need Versioning?

    View Slide

  14. Why Do We Need Versioning?
    for breaking things
    in controlled fashion

    View Slide

  15. How to Version?

    View Slide

  16. How to Version?
    You need:
    Deprecation schedules

    View Slide

  17. How to Version?
    You need:
    Deprecation schedules
    Changelogs / upgrade notes

    View Slide

  18. Versioning Schemes

    View Slide

  19. Versioning Schemes
    AcceptHeaderVersioning (DRF)
    GET /projects HTTP/1.0
    Accept: application/json; version=1

    View Slide

  20. Versioning Schemes
    AcceptHeaderVersioning (DRF)
    GET /projects HTTP/1.0
    Accept: application/json; version=1
    URLPathVersioning (DRF)
    GET /v1/projects HTTP/1.0
    Accept: application/json

    View Slide

  21. Versioning Schemes Cont.
    Integers ( v1 ) vs dates ( 2018-08-24 )?

    View Slide

  22. Versioning Schemes Cont.
    Integers ( v1 ) vs dates ( 2018-08-24 )?
    Dates are less emotional

    View Slide

  23. Versioning Schemes Cont.
    Integers ( v1 ) vs dates ( 2018-08-24 )?
    Dates are less emotional
    Easier internal / test versions

    View Slide

  24. Version Transformers

    View Slide

  25. Version Transformers
    » » Requests into newer version » »
    Core code is for latest version
    « « Responses into older version « «

    View Slide

  26. Version Transformers
    » » Requests into newer version » »
    Core code is for latest version
    « « Responses into older version « «
    Won't work for big, breaking changes

    View Slide

  27. Authentication &
    Authorization

    View Slide

  28. Token Authentication
    Clients send HTTP header, ala
    Authorization: Token 9944b09199c62bcf9418

    View Slide

  29. OAuth 2.0

    View Slide

  30. OAuth 2.0
    For creating platforms

    View Slide

  31. OAuth 2.0
    For creating platforms
    Complex, but solves many issues

    View Slide

  32. OAuth 2.0
    For creating platforms
    Complex, but solves many issues
    Many packages, e.g. Django OAuth Toolkit,
    OAuthLib

    View Slide

  33. Standardize!

    View Slide

  34. Standardize!
    Standards help:
    bring familiarity

    View Slide

  35. Standardize!
    Standards help:
    bring familiarity
    avoid common pitfalls

    View Slide

  36. Standardize!
    Standards help:
    bring familiarity
    avoid common pitfalls
    historically, standardized approaches win

    View Slide

  37. JSON API
    http://jsonapi.org/
    one potential standard to use

    View Slide

  38. JSON API
    http://jsonapi.org/
    one potential standard to use
    GraphQL is another option

    View Slide

  39. Standardize Structure

    View Slide

  40. Standardize Structure
    Responses have predictable, familiar
    structure

    View Slide

  41. GET https://example.com/api/v1/projects
    {
    "links": {
    "next": "https://example.com/api/v1/projects?cursor=cD0yMDE4L",
    "prev": null
    },
    "data": [...],
    "included": [...]
    }

    View Slide

  42. "data": [
    {
    "type": "project",
    "id": "289",
    "links": {
    "self": "https://example.com/api/v1/projects/289"
    },
    "attributes": {
    "created": "2018-06-28T22:52:08.690486Z",
    "name": "Allison-Patterson",
    "description": "aggregate collaborative models"
    },
    "relationships": {...}
    },
    ...
    ],

    View Slide

  43. "data": [{ ...
    "relationships": {
    "created_by": {
    "data": {
    "type": "user",
    "id": "199"
    }
    },
    "epics": {
    "data": [
    {
    "type": "epic",
    "id": "3101"
    }
    ],
    }
    } }, ...
    ],

    View Slide

  44. "included": [
    {
    "type": "epic",
    "id": "3101",
    "attributes": {
    "created": "2018-06-28T22:50:45.885691Z",
    "name": "Ergonomic background extranet"
    },
    "links": {
    "self": "https://example.com/api/v1/epics/3101"
    }
    },
    {
    "type": "user",
    "id": "199",
    "attributes": {...}
    }
    ]

    View Slide

  45. Impressions?

    View Slide

  46. Flexibility
    Con gurable elds:
    GET https://example.com/api/v1/projects
    GET https://example.com/api/v1/projects \
    ?included=comments
    GET https://example.com/api/v1/projects \
    ?included=comments&fields[project]=name,comments

    View Slide

  47. Pagination
    List responses have next / prev links
    {
    "links": {
    "next": "https://example.com/api/v1/projects?cursor=cD0yMDE4L",
    "prev": null
    },
    "data": [...],
    }

    View Slide

  48. Pagination
    List responses have next / prev links
    {
    "links": {
    "next": "https://example.com/api/v1/projects?cursor=cD0yMDE4L",
    "prev": null
    },
    "data": [...],
    }
    Cursor-based pagination FTW (but YMMV).

    View Slide

  49. Errors

    View Slide

  50. Errors
    POST https://example.com/api/v1/projects
    {
    "errors": [
    {
    "title": "Invalid Attribute",
    "detail": "Name must contain at least three letters.",
    "source": { "pointer": "/data/attributes/name" },
    "code": "name_too_short",
    "status": "422"
    }
    ]
    }

    View Slide

  51. Special Cases
    For when you have LOTS of data

    View Slide

  52. Special Cases
    For when you have LOTS of data
    out-of-band approach

    View Slide

  53. GET https://example.com/api/v1/datasets/123
    {
    "data": {
    "type": "dataset",
    "id": "123",
    "attributes": {
    "name": "CIFAR10 dataset",
    },
    "links": {
    "data_tgz": "https://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz",
    "self": "https://example.com/api/v1/datasets/123"
    }
    }
    }

    View Slide

  54. Standardization Matters
    the speci c standard isn't that important
    GraphQL, etc are also good options

    View Slide

  55. Documentation

    View Slide

  56. Documentation
    Often overlooked

    View Slide

  57. Documentation
    Often overlooked
    Gives the rst impression

    View Slide

  58. Documentation
    Often overlooked
    Gives the rst impression
    The e ort is worth it!

    View Slide

  59. Creating
    Awesome Docs

    View Slide

  60. What Should Go In There?

    View Slide

  61. What Should Go In There?
    How do I access it?

    View Slide

  62. What Should Go In There?
    How do I access it?
    Do I need developer account?

    View Slide

  63. What Should Go In There?
    How do I access it?
    Do I need developer account?
    Root URL, etc

    View Slide

  64. What Should Go In There?
    How do I access it?
    Do I need developer account?
    Root URL, etc
    Authentication info

    View Slide

  65. What Should Go In There?
    General encodings, formats, etc

    View Slide

  66. What Should Go In There?
    General encodings, formats, etc
    Versioning, pagination, etc

    View Slide

  67. What Should Go In There?
    General encodings, formats, etc
    Versioning, pagination, etc
    Common errors

    View Slide

  68. What Should Go In There?
    General encodings, formats, etc
    Versioning, pagination, etc
    Common errors
    Code for getting started

    View Slide

  69. The Endpoints

    View Slide

  70. The Endpoints
    URL & operations

    View Slide

  71. The Endpoints
    URL & operations
    Request/response data

    View Slide

  72. The Endpoints
    URL & operations
    Request/response data
    Optional parameters

    View Slide

  73. The Endpoints
    URL & operations
    Request/response data
    Optional parameters
    Permissions etc

    View Slide

  74. Keep it Fresh!

    View Slide

  75. Keep it Fresh!
    Obsolete docs are the worst

    View Slide

  76. Keep it Fresh!
    Obsolete docs are the worst
    Always autogenerate!

    View Slide

  77. Keep it Fresh!
    Obsolete docs are the worst
    Always autogenerate!
    Usually code » schema » docs

    View Slide

  78. Schema & Autogeneration

    View Slide

  79. Schema & Autogeneration
    OpenAPI, Swagger, etc

    View Slide

  80. Schema & Autogeneration
    OpenAPI, Swagger, etc
    Use your tools

    View Slide

  81. Schema & Autogeneration
    OpenAPI, Swagger, etc
    Use your tools
    Combine docs & code examples

    View Slide

  82. Schema & Autogeneration
    OpenAPI, Swagger, etc
    Use your tools
    Combine docs & code examples
    Client libs autogeneration

    View Slide

  83. In Summary
    Embrace standards (e.g. JSON API)
    Invest in documentation
    Use automation
    Reduce friction

    View Slide

  84. Thanks!
    Rivo Laks ⋅ @rivolaks ⋅ rivolaks.com
    tinyurl.com/TODO

    View Slide