carrot / restful-api-spec

Carrots spec/process for building RESTful APIs
MIT License
14 stars 0 forks source link

Base Interface Change #8

Open BrandonRomano opened 7 years ago

BrandonRomano commented 7 years ago

Here's a quick proposal for a change to our base interface... I've chatted with @rmfarrell, and he has also independently come up with this solution, as he's run into the same exact problem with our base interface.

Currently

Currently, our base interface is this:

{
    "success": true,
    "status_code": 200,
    "status_text": "OK",
    "error_details": [
        {
            "code": 1,
            "text": "Invalid email"
        }
    ],
    "content": {
        // ...
    }
}

I've not run into many problems with this base interface in use, but documenting this base interface in swagger is extremely repetitive, due to the lack of flexibility of json-ref (not to the fault of json-ref, it's just how it is).

Currently, for documenting an endpoint swagger documentation ends up looking like something like this:

get:
  tags:
  - Applications
  summary: Index
  description: Fetches and displays all applications.
  produces:
  - application/json
  responses:
    200:
      description: OK
      schema:
        type: object
        properties:
# ----------------------------------------
          success:
            type: boolean
          status_code:
            type: integer
          status_text:
            type: string
          error_details:
            type: array
            items:
              $ref: '#/definitions/ErrorDetail'
# ----------------------------------------
          content:
            type: array
            items:
              $ref: '#/definitions/Application'

Proposal

If we wrap all of the non-content information in a meta object, we'll be able to use a json-ref for all of its content.

{
    "meta": {
        "success": true,
        "status_code": 200,
        "status_text": "OK",
        "error_details": [
            {
                "code": 1,
                "text": "Invalid email"
            }
        ]
    },
    "content": {
        // ...
    }
}

Then our swagger for each endpoint would look something more like this

get:
  tags:
  - Applications
  summary: Index
  description: Fetches and displays all applications.
  produces:
  - application/json
  responses:
    200:
      description: OK
      schema:
        type: object
        properties:
# ----------------------------------------
          meta:
            $ref: '#/definitions/Meta'
# ----------------------------------------
          content:
            type: array
            items:
              $ref: '#/definitions/Application'
kylemac commented 7 years ago

a bit of a digression but have we investigated (and subsequently dismissed) this existing spec - http://jsonapi.org/ ?

jescalan commented 7 years ago

This might be totally too far of a tangent, but this seems like it would be a really great candidate for GraphQL ✨

BrandonRomano commented 7 years ago

@kylemac I've totally checked it out recently actually.

This change was largely brought back into my mind because of the readings from there.

Beyond the value of matching an existing specification, I didn't find any additional value in switching to match anything else from that spec (beyond this).

kylemac commented 7 years ago

@BrandonRomano that's enough for me. just wanted to be sure we weren't looking past it

BrandonRomano commented 7 years ago

Nope, I still to plan to go through it again with a fine-tooth comb, and I will close out #7 once I end up doing that.

I did a high level sweep of it last week during some down-time

BrandonRomano commented 7 years ago

But, in short it felt the JSON API specification seemed to trade a lot of fluency for standardization, which IMO wouldn't be a win for us. It was particularly specific on how you should define relationships and your data.

kylemac commented 7 years ago

👍 from me. Makes sense

BrandonRomano commented 7 years ago

@tmilewski, thoughts? Want to get a unanimous decision on this one before I go and do this