Dealerware

Reference


Deep dive into our reference documentation!

  • Attribute Naming
    • Booleans should not use is_ or has_ in names, e.g. enabled, not is_enabled
    • Dates should use _on naming convention, e.g. expires_on
    • Time should use _at naming convention, e.g. created_at
  • Dates and Times
    • Dealerware uses standardized dates and times issued by the International Organization for Standardization (ISO). All dates and times should be in UTC format with ISO8601 formatting, localized appropriately.
  • Granularity

    Chatty interaction with one resource over coarse response with multiple resources

    • No conditional responses.
    • If attributes are required in request/response, they should always be included.

    Fine-grained resources allow for simpler caching strategies

    Specialized resources can simplify API interactions and reduce complexity and maintenance.

    Changing any attribute on a booking in a single request multiplies complexity. Clients only modify some attributes at a time, so we can make simpler API interactions to support that.

    • PUT /bookings/:id - modify pickup, dropoff
    • PUT /bookings/:id/coverages - modify booking coverage
    • PUT /bookings/:id/fleet - modify booking fleet
  • HTTP Status Codes

      Use specific HTTP codes when applicable, not just 200, 400

    • Single GET resource to avoid mass duplication of responses, not including collections, search functionality.
      Example:
    • Only GET /cars/:id returns JSON representation of a Car in response body with a 200 response code
    • POST /cars returns Location header with https://api.dealerware.com/cars/2 without a response body
    • PUT /cars/2 returns 204 response code without a response body, client can refresh state with GET /cars/2
    • GET /cars/search returns 200 response code with collection of Car in response body, may (but not must be) same response body as GET /cars/:id
    • GET /cars returns 200 response code with collection of Car in response body, may (but not must be) same response body as GET /cars/:id
  • Hypermedia Links
    • Link to dependent/associated resources over duplicating data inside endpoints
    • Example: GET /cars/2 has an attribute links
      • { "id": 2, "make": "Audi", "links": { "fleet": { "id": 4, "href": "https://api.dealerware.com/fleets/4" } } }
  • Internationalization
    • All our units are in metric
    • API responses are specific to unit type only for clarity:
      • { "odometer": { "value": 12.34, "unit": "km" } }
  • JSON Only
    • Technically, only respond to JSON MIME type
    • No PDF, JPG, HTML, etc
    • Can provide links to resources- e.g. a json response that has a url attribute
    • Return 406 HTTP error unless request accepts json
      • Valid list of Accept values: application/json, application/*, */*
    • Return 415 HTTP error unless requests send json
      • When data is in request body (POST, PUT), must be application/json or multipart/form-data
      • JSON parsing error always returns 415
  • Pagination
    • Every collection should be paginated
    • Pagination details are returned via headers
      • Total - total number of records
      • Page - current page number returned
      • Per-Page - number of records returned per page
    • Optionally, pagination links returned via Link header
      • Example: Link header contains array of links
        • https://api.dealerware.com/locations?page=1; rel="first", https://api.dealerware.com/locations?page=10; rel="last", https://api.dealerware.com/locations?page=2; rel="next"
    • Minimum, maximum, default page size
      • Examples: 10, 100, 25
    • Page controlled via page query param
      • Example: GET /locations?page=2
    • Records per page controlled via page_per query param
      • Example: GET /locations?page=2&per_page=100
  • Resource Naming
    • Nouns over verbs
    • Plural over singular
      • Good: /reservations, /reservations/:id
      • Bad: /reservation, /reservation/:id
      • Singular resources are valid resources
        • Example: A user has one driver's license
        • GET /user/drivers_license instead of GET /user/drivers_license
    • snake_case
      • Good: car_reservation
      • Bad: car-reservation, CarReservation, carReservation
    • Consistency
    • Prefer nested resources over long_resource_names
      • Prefer GET /rentals/1/emails/receipt over GET /rentals/1/email_receipt
  • Root Envelopes
    • No root level envelopes unless necessary
      • Grouping child data can be useful, such as address attributes within location
        • { "id": 1, "name": "Audi Dealership", "address": { "id": 3, "line1": "211 E 7th St" } }
        • Envelopes are wrappers in request/response bodies, such as car in this Example
          • With Envelope: { "car": { "id": 1, "make": "Audi" } }
          • Without Envelope: { "id": 1, "make": "Audi" }
        • Utilizing headers reduces the need for metadata in request/response envelopes
  • Schema
    • All API access is over HTTPS, and accessed from https://api.dealerware.com. All data is sent and received as JSON. Will receive 406 HTTP error unless request accepts JSON and will receive 415 HTTP error unless requests send JSON.
      • Valid list of Accept values: application/json, application/*, */*
      • Request body must be application/json or multipart/form-data
      • JSON parsing error always returns 415
  • Sorting
    • Must whitelist attributes that can be sorted
      • Names accessed by contact attribute name, not database attribute name, but they can be the same
        • Abstraction layer between contract attribute and database to prevent SQL injection
    • Controlled via sort query param, using optional - operator for ascending vs descending
      • Example: sort=location_id,created_at - sort by location_id asc, created_at asc
      • Example: sort=location_id,created_at -sort by location_id asc, created_at desc
      • Example: sort=location_id,created_at -sort by location_id desc, created_at desc