aj-foster / open-api-generator

Open API code generator for Elixir
MIT License
97 stars 13 forks source link

Is it possible to generate more fulsome types than ":map" for object responses? #38

Closed jinfiesto closed 4 months ago

jinfiesto commented 7 months ago

Firstly, thanks for starting this project. As great as Elixir ecosystem is, it doesn't seem to have great tooling around OpenAPI.

If I have a section of an OpenAPI spec that looks like:

responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  projects:
                    type: array
                    items:
                      $ref: "#/components/schemas/project"
                  nextPageToken:
                    type: string

This is what gets generated in the generated code:

response: [{200, :map}, {400, :null}, {401, :null}],

Is it possible to get a more fulsome type than :map here? It'd be great if this could auto-generate something like a list_projects_response schema to use as a struct. I'm currently converting the map into a struct by doing some post processing, but it'd be nice if I could avoid doing this, as it's a bit brittle in the case of the OpenAPI spec changing.

aj-foster commented 7 months ago

Hi there πŸ‘‹πŸΌ

I agree that it would be great to have better types in this situations. Some specs rely on these kinds of definitions heavily or exclusively.

Since you have experience converting them, I'm curious: what options should be available for expressing these objects? You mentioned one already: turning these schemas into structs. Are there situations in which you might prefer an inline type or something less than a full struct? What might that look like?

jinfiesto commented 7 months ago

In my specific use case, I was testing generating GQL schemas from structs via a macro, so in my particular use case, I was pretty locked into a struct. That being said, in a use case where I was less locked into a struct, it seems like the right options are either struct or inline type as you outlined.

Upon further reflection, to me it seems like inline type is likely the sensible default in most cases. While we use the kinds of definitions above heavily, we don't generally inline the definition of say an entire domain object as above, so those would still get a proper struct representation. I would imagine most people write their specs this way. In most normal use cases, I can't really imagine too many scenarios where I would expect someone to prefer having a struct vs the inline type.

aj-foster commented 5 months ago

Hello again πŸ‘‹πŸΌ

Release 0.1.0-rc.4 has changes to help with this. If you have a chance, please try it out and let me know how it works for you.