DoclerLabs / api-client-generator

API client generator is a console application capable of generating an API client based on OpenAPI(Swagger) specification.
MIT License
31 stars 19 forks source link

Unable to get response headers in case of no content #71

Open szhajdu opened 2 years ago

szhajdu commented 2 years ago

When generating a client where response body is empty I'm not able to get the response object to check headers when needed.

Example

openapi: "3.0.0"
info:
  version: 1.0.0
  title: Swagger Petstore
  license:
    name: MIT
servers:
  - url: http://petstore.swagger.io/v1
paths:
  /pets/{petId}:
    parameters:
      - name: petId
        in: path
        required: true
        description: The id of the pet
        schema:
          type: string
    put:
      summary: Create a pet
      operationId: createPet
      tags:
        - pets
      responses:
        '204':
          description: No content
          headers:
            x-foo:
              description: Something important
              schema:
                type: string

Is there any other way to get response object after executing request in api clients?

JasonBenett commented 2 years ago

Hello,

There is a "hacky" way indeed. Instead of using the generated method createPet() you have a generic method sendRequest() which does not map the response to an entity but returns directly the ResponseInterface implementation.

vsouz4 commented 2 years ago

Right now there's no "proper" support for retrieving headers from response, regardless of having body defined. Unless you call "sendRequest" manually and work with the PSR response object. (as suggested by @JasonBenett)

The name of the classes returned by the ApiClient class are pretty tied to 200/201 (ResponseBody). 204 meaning no content also means no body 😄 but still you'd need something to be returned so you could ->getHeaders() for example.

Ideally I guess we would need to introduce an extra layer (if we really want to be able to ->getHeaders() calling the operationName methods from ApiClient). So that you'd call e.g. $myApiClient->getPet()->getBody() and $myApiClient->getPet()->getHeaders(), with getBody() returning the ResponseBody which is currently returned under ->getPet() directly...

we could also tweak the existent ResponseBody adding the headers there, although it feels weird to work with a concrete ResponseBody object for a 204 response which has no body... so maybe we could rename the class, but also we could have issues with mixing something like "getHeaders()" which would return HTTP response headers with a "getHeaders()" from a response that has {"headers": ...} in the payload

So either using sendRequest manually as a workaround or we'd need to introduce an extra layer (even though this breaks backward compatibility, it's I guess safer and more consistent - you get Response and inside you have body and headers).

szhajdu commented 2 years ago

Thank you guys, I’ll go with sendRequest for now.

I could also imagine a getLastResponse method, which would return always the response of the last executed API call. It could be useful in a few test scenarios as well but also would require introducing a state into the client.