Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

High Level Requirements

  • Consumer-Perspective. Design your API from the perspective of the consumer, NOT the perspective of your underlying implementation.  For example:
    • If the underlying implementation requires accessing multiple models or multiple apps/projects, this does not need to be reflected in a public interface.  From the perspective of the consumer, it's simply one thing they are requesting.
    • Keep CRUD operations together within its corresponding resource.  Why have the client go to one resource to read it and then another resource to write it?
  • Simple.  Keep the top-leveI resources clear and simple - focusing on what the client is looking to consume.  You can hide complexity within the parameters.
  • Separation of concerns.  Do not require the consumer to know any implementation details.  For example, an API shouldn't require the client to know the inter-dependencies of fields.  Rather, all such business rules should be owned by the server.  This allows the client to be lightweight and easily maintainable in the future.
  • Explicit Support Levels. APIs should make it clear whether they are experimental or more permanent as a part of their documentation.
  • Discoverability. Support HATEOAS where possible.  This allows us to change our URLs without needing to worry about updating the mobile apps if the app discovers its URLs from a base URL.

Conventions

1. URL Naming

...

  • Nice: Do not expose database IDs where possible (Must for external APIs, per dev ops)
  • Must: edX resource identifiers
    • Users should be referenced by username.

    • Courses runs should be referenced via course run keys (eg. course-v1:edX+BlendedX+1T2018)
    • Catalog courses should be referenced via a catalog UUID.
    • Course blocks should be referenced via usage keys (eg. block-v1:org+course+run+type@sequential+block@2aa6fc9d8278)
  • Explicit Filters
    • Model system resource URL schemes as if all resources are available to all users
    • Include all necessary filters in the URL such that any user could theoretically access the resource
    • Anchor
      username
      username
      Separate filtering and authorization – ie, do not return different resource representations via the same URL based on the requesting user 
      • Example 1:  "/profiles/john_harvard" versus "/profile"
      • Example 2:  "/courses?username=john_harvard" versus "/courses"
    • Remember, it's entirely possible that "/profiles/john_harvard" or "/courses?username=john_harvard" could be requested by the "administrator" user

    • Several benefits exist from an explicit filtering approach:
      • Ensures resources/results are individually-addressable
      • Enables discovery/sharing of resources, among other potential uses
      • Resource filtering mechanisms can be modified without impacting authorization mechanisms
      • Intermediate network gear can cache resource representations to improve performance (for open/unprotected resources)

  • Composite Resource (with multiple dimensions)
    • If an endpoint represents a relationship among multiple dimensions, the dimensions can be specified in the following ways:
    • As filter parameters:
      • /api/enrollments/v1/enrollments/?user={username}&course={course_id}
    • As comma-delimited resource keys in the URL:
      • /api/enrollments/v1/enrollments/{username},{course_id}
    • As a UUIDs to uniquely identify the relationship:
      • /api/enrollments/v1/enrollments/{enrollment_id}

...