fern-api / fern

Input OpenAPI. Output SDKs and Docs.
https://buildwithfern.com
Apache License 2.0
2.67k stars 149 forks source link

[spec] Add `headers` to response #2065

Open csm-kb opened 1 year ago

csm-kb commented 1 year ago

Hey gang! I've been really enjoying Fern's ease-of-use and am piloting a proof-of-concept API specification for our next project.

One thing that surprised me to find was (in addition to #1583) that we currently can't define response headers for the API to expect to return (thus a client to receive) for a given response.

Stripe, for example, takes advantage of a Request-Id header to provide a UUID for an API response that can be leveraged for support requests and tracing -- and we would like to accomplish similarly in the explicit specification.

Other notes:

dsinghvi commented 1 year ago

Hey @csm-kb thanks for filing the issue! Would be valuable for me to understand what other generators you are using where you would want this response functionality plumbed through?

csm-kb commented 1 year ago

@dsinghvi For sure! We're looking to leverage the following generators:

Minimally the first two to start!

dsinghvi commented 1 year ago

@csm-kb perfect -- do you need to access the response headers in the SDK ? Typically users don't need to do that so declaring the response headers in the fern definition won't actually affect the generated code.

All to say -- you can define your endpoints and the SDKs will work as you expect. The same is true for status codes, the sdks will appropriately handle any success status codes even if it's not exactly a 200.

csm-kb commented 1 year ago

@dsinghvi our use case currently involves accessing the response headers and status codes for various responses! Easiest parallel example is Stripe providing Request-Id, as I mentioned in my OP -- a dirtier example (not recommended if you value your eyes) is AWS docs surrounding fetching response metadata.

Should we continue that way, we would like our SDKs to expose/handle those defined in the API specification -- both of which (not to double-dip the status code FR, as that is not the focus of this FR) are common use cases among the enterprise client SDKs I've interfaced with (Stripe and AWS, as two of many).

This naturally ties to a fundamental question I've seen countless devs debate:

Should response metadata be captured on the envelope, or in the response body?

This depends on Fern's cultural modus operandi, which I'm not versed well enough in yet to understand. To the above from my experience, both are preferences that may want be catered to to encourage folks to migrate to Fern, after which they can then be encouraged to migrate their metadata to the cultural standard -- e.g. the body rather than the envelope! However, I could easily be wrong here, and funneling the choice could be an already-made strategic design decision.

Anyway, specific to the FR, here is a response header example for what I'm imagining:

imports:
  types: types.yml

service:
  auth: true
  base-path: /service
  endpoints:
    GetData:
      docs: Retrieve a list of data for a given ID
      method: GET
      path: /data
      request:
        name: GetData
        query-parameters:
          id:
            type: types.DataId
            allow-multiple: true
      response:
        type: list<types.DataObject>
        headers:                                                <--
          Request-Id: types.ApiRequestId                        <--
      errors:
        - DataNotFoundError
      examples:
        # Success response
        - query-parameters:
            id: data123
          response:
            body:
              - $types.DataObject.example
            headers:                                            <--
              Request-Id: $types.ApiRequestId.example           <--

Context / assumption breakers: