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

Generates duplicate types and wrong references to enums

Open markussiebert opened this issue 2 years ago • 1 comments

Hi,

I am trying to generate a client with the following config:

package: "adguardhome"
generate:
  models: true
  embedded-spec: true
  client: true
output: pkg/go-adguard-home/client.go
output-options:
  skip-prune: false
  client-type-name: AdguardHomeClient

with this openapi

https://raw.githubusercontent.com/AdguardTeam/AdGuardHome/master/openapi/openapi.yaml

But have some minor issues:

  1. Duplicate Types
// AccessListResponse Client and host access list.  Each of the lists should contain only unique elements.  In addition, allowed and disallowed lists cannot contain the same elements.
type AccessListResponse = AccessList

// ClientsFindResponse Client search results.
type ClientsFindResponse = []ClientsFindEntry

...

type AccessListResponse struct {
	Body         []byte
	HTTPResponse *http.Response
        // Think this reference to self is "wrong" and the other type should be used
	JSON200      *AccessListResponse
}

type ClientsFindResponse struct {
	Body         []byte
	HTTPResponse *http.Response
         // Think this reference to self is "wrong" and the other type should be used
	JSON200      *ClientsFindResponse
}

I think this collision is unintended and only because the "schema" that is referenced has the same name as the generated type for the answer of the get request.

For the second type collision x-go-name rewrite works, for the first it does not

    'AccessListResponse':
      'x-go-name': 'AccessListResponseType'
      '$ref': '#/components/schemas/AccessList'
    'AccessSetRequest':
      '$ref': '#/components/schemas/AccessList'
    'AccessList':
      'description': >
        Client and host access list.  Each of the lists should contain only
        unique elements.  In addition, allowed and disallowed lists cannot
        contain the same elements.
      'properties':

this does not work,

  'ClientsFindResponse':
      'x-go-name': 'ClientsFindResponseType'
      'type': 'array'
      'description': 'Client search results.'
      'items':
        '$ref': '#/components/schemas/ClientsFindEntry

this works as expected

  1. Wrong references for enums
// Defines values for DNSConfigBlockingMode.
const (
	CustomIp DNSConfigBlockingMode = "custom_ip"
	Default  DNSConfigBlockingMode = "default"
	NullIp   DNSConfigBlockingMode = "null_ip"
	Nxdomain DNSConfigBlockingMode = "nxdomain"
	Refused  DNSConfigBlockingMode = "refused"
)

... 

type DnsInfoResponse struct {
	Body         []byte
	HTTPResponse *http.Response
	JSON200      *struct {
		BlockingIpv4 *string           `json:"blocking_ipv4,omitempty"`
		BlockingIpv6 *string           `json:"blocking_ipv6,omitempty"`
                // think this should be DNSConfigBlockingMode, as there is no other blocking mode in the openapi.yaml
		BlockingMode *N200BlockingMode `json:"blocking_mode,omitempty"`

the openapi lines matching this seem to be

  '/dns_info':
    'get':
      'tags':
      - 'global'
      'operationId': 'dnsInfo'
      'summary': 'Get general DNS parameters'
      'responses':
        '200':
          'description': 'OK'
          'content':
            'application/json':
              'schema':
                'allOf':
                - '$ref': '#/components/schemas/DNSConfig'
                - 'type': 'object'
                  'properties':

and

    'DNSConfig':
      'type': 'object'
      'description': 'Query log configuration'
      'properties':
        'bootstrap_dns':
          'type': 'array'
          'description': >
            Bootstrap servers, port is optional after colon.  Empty value will
            reset it to default values.
          'items':
            'type': 'string'
          'example':
          - '8.8.8.8:53'
          - '1.1.1.1:53'
        'upstream_dns':
          'type': 'array'
          'description': >
            Upstream servers, port is optional after colon.  Empty value will
            reset it to default values.
          'items':
            'type': 'string'
          'example':
          - 'tls://1.1.1.1'
          - 'tls://1.0.0.1'
        'upstream_dns_file':
          'type': 'string'
        'protection_enabled':
          'type': 'boolean'
        'dhcp_available':
          'type': 'boolean'
        'ratelimit':
          'type': 'integer'
        'blocking_mode':
          'type': 'string'
          'enum':
          - 'default'
          - 'refused'
          - 'nxdomain'
          - 'null_ip'
          - 'custom_ip'

somehow this isn't resolved correctly As I am new into openapi and generating clients, I don't know if it something that I should solve via config - or a bug (in oapi-codegen - or the openapi yaml). Would be great if I could get some input on this issues.

markussiebert avatar Dec 13 '22 20:12 markussiebert

I was experiencing the same issue for duplicate types. The issue is that oapi-codegen does not check if the type name it generates for paths.<path>.responses is not already taken by a schema in components.schema. Since schemas can have any name I think oapi-codegen should avoid creating type names which are already taken up by schemas.

I have created a minimal reproducible example: https://github.com/Moomboh/mre-oapi-codegen-type-collisions

@markussiebert The wrong references for enums are a separate issue, I think. So this should maybe be moved to its own issue.

Moomboh avatar Dec 19 '22 12:12 Moomboh

Still an issue

filinvadim avatar Oct 04 '23 19:10 filinvadim