oapi-codegen icon indicating copy to clipboard operation
oapi-codegen copied to clipboard

Hide certain property in schema

Open hiddenmarten opened this issue 1 year ago • 8 comments

Hi!

I'm new to oapi-codegen and absolutely love it!

I'm working on generating models for use with gorm, and I'm facing a challenge with needing actual references to structs in the models.

I wanted to ask if it's possible to add support for assigning an OpenAPI extension directly to a $ref using allOf. This would be extremely useful for my use case.

Here’s an example:

components:
  schemas:
    Ingredient:
      type: object
      properties:
        id:
          type: integer
          format: int64
          x-oapi-codegen-extra-tags:
            gorm: primarykey
        name:
          type: string
          example: "Tomato"
          x-oapi-codegen-extra-tags:
            gorm: unique;not null
    RecipePosition:
      type: object
      properties:
        ingredientId:
          type: integer
          format: int64
          x-oapi-codegen-extra-tags:
            gorm: not null
        ingredient:
          allOf:
            - $ref: '#/components/schemas/Ingredient'
            - x-go-json-ignore: true

Additionally, I had the idea to introduce an OpenAPI extension like x-oapi-codegen-extra-properties, which would parse and generate such structs. This extension would be hidden from the actual OpenAPI spec but would effectively solve the situation. Here's an example:

components:
  schemas:
    Ingredient:
      type: object
      properties:
        id:
          type: integer
          format: int64
          x-oapi-codegen-extra-tags:
            gorm: primarykey
        name:
          type: string
          example: "Tomato"
          x-oapi-codegen-extra-tags:
            gorm: unique;not null
    RecipePosition:
      type: object
      properties:
        ingredientId:
          type: integer
          format: int64
          x-oapi-codegen-extra-tags:
            gorm: not null
      x-oapi-codegen-extra-properties:
        ingredient:
          $ref: '#/components/schemas/Ingredient'

Also, I'd be honored to volunteer to implement this feature if needed!

P.S. For me the second option looks much helpful since it will completely hide certain properties from the spec, but it would be used from gorm as is.

hiddenmarten avatar Sep 05 '24 18:09 hiddenmarten

Re the first question, have you tried it? If so, with which version? At a glance I'm not quite sure if it'd work so may want some tweaking

Re the latter, the Overlay functionality looks like what you want - either so you can have a nice public-facing API and then use Overlay to modify the schema before you generate code from it, or you have your spec contain all the info you need to generate code from it, then use Overlay to remove anything you don't want

(note that that's not yet released so https://github.com/oapi-codegen/oapi-codegen?tab=readme-ov-file#pinning-to-commits)

I wouldn't see the latter as a feature request that we'd want to fulfill - we want to encourage any required fields to be added to the OpenAPI spec - internal information should be avoided

jamietanna avatar Sep 08 '24 17:09 jamietanna

Hi again!

the first question, have you tried it? If so, with which version?

I tried it with the last published version v2.3.0, and as a result, it generates models like:

// RecipePosition defines model for RecipePosition.
type RecipePosition struct {
	Ingredient *struct {
		Id        *uint      `json:"id,omitempty"`
		Name      *string    `json:"name,omitempty"`
	} `json:"ingredient,omitempty"`
	IngredientId *uint `json:"ingredientId,omitempty"`
}

the Overlay functionality looks like what you want - either so you can have a nice public-facing API and then use Overlay to modify the schema before you generate code from it, or you have your spec contain all the info you need to generate code from it, then use Overlay to remove anything you don't want

I didn't know about such functionality and I definitely should try it!

Thank you for such a detailed explanation, I believe this issue can be closed.

P.S. If you want me to put some effort into making allOf work with OpenAPI extensions I can give it a shot.

hiddenmarten avatar Sep 08 '24 17:09 hiddenmarten

I looked at the Overlay functionality in oapi-codegen, and it's an impressive feature! It's beneficial for separating internal specification details from the public API.

However, in my case, I need to add custom Go tags directly to the generated structs. As far as I can tell, this doesn't seem to be supported at the moment, or I might be missing the correct approach to do it.

I'll try to deal with it if you have no objections ;)

hiddenmarten avatar Sep 10 '24 20:09 hiddenmarten

To confirm, would Overlay + x-oapi-codegen-extra-tags not give you what you need?

jamietanna avatar Sep 10 '24 20:09 jamietanna

Yes, the result is essentially the same from a code perspective in both cases, whether you use an overlay or not, which is expected I beleive.

hiddenmarten avatar Sep 10 '24 20:09 hiddenmarten

Great, in which case are we OK to close this? Or have I missed something else needed here?

jamietanna avatar Sep 10 '24 20:09 jamietanna

I'll prepare a pull request soon, with a fix for my case and a dedicated test following the project flow.

Then, I believe, it's your call whether you want to merge it or not :)

hiddenmarten avatar Sep 10 '24 20:09 hiddenmarten

Ready to review, I believe.

https://github.com/oapi-codegen/oapi-codegen/pull/1756

hiddenmarten avatar Sep 12 '24 14:09 hiddenmarten