swagger-api / swagger-codegen

swagger-codegen contains a template-driven engine to generate documentation, API clients and server stubs in different languages by parsing your OpenAPI / Swagger definition.
http://swagger.io
Apache License 2.0
16.89k stars 6.03k forks source link

Generate enums with integer values assigned #2690

Open kenjitayama opened 8 years ago

kenjitayama commented 8 years ago

I want to generate enum with integer values assigned.

Swift:

enum Weather: Int {
    case Sunny = 1
    case Cloudy = 2
    case Rainy = 3
}

Java:

public enum Weather {
    Sunny(1),
    Cloudy(2),
    Rainy(3);

    private final int type;

    private Weather(final int price) {
        this.type = type;
    }

    public type getType() {
        return type;
    }
}

But I couldn't figure out how to do this.

In the Swagger 2.0 specs, it references JSON Schema specs for enum. It says any type can be used, but it seems like type needs to be string for generating enums. Like this:

definitions:
  weather:
    type: object
    required:
      - type
    properties:
      type:
        type: string
        enum:
          - Sunny
          - Cloudy
          - Rainy

If I change type to integer, no enum is generated, and it will be a plain integer property.

Firstly, I couldn't find how to assign integers to enum items using Swagger specs.

Are there any plans or workarounds to support this kind of enum?

wing328 commented 8 years ago

@kenjitayama For Java, it will be taken care of by https://github.com/swagger-api/swagger-codegen/pull/2508, which adds better support for enum (number, string, special characters) in PHP, C# and Java.

For Swift, we want to do it as part of https://github.com/swagger-api/swagger-codegen/pull/2508 as well. Currently, we're adding better enum support for JS in that PR.

kenjitayama commented 8 years ago

Thanks for the quick response! I will be watching the issue 👍

wing328 commented 8 years ago

@kenjitayama https://github.com/swagger-api/swagger-codegen/pull/2508 has been merged into master so it should cover at least Java. Please pull the latest master and give it a try.

kenjitayama commented 8 years ago

@wing328 Thanks for the notice! Looking forward for Swift support too :)

I wasn't sure of the supported yaml syntax and I tried the following. Only weather3 generated an enum.

definitions:
  weather1:
    type: object
    required:
      - type
    properties:
      type:
        type: integer
        enum:
          - Sunny
          - Cloudy
          - Rainy
  weather2:
    type: object
    required:
      - type
    properties:
      type:
        type: integer
        enum:
          - 1
          - 2
          - 3
  weather3:
    type: object
    required:
      - type
    properties:
      type:
        type: integer
        format: int32
        enum:
          - 1
          - 2
          - 3
  weather4:
    type: object
    required:
      - type
    properties:
      type:
        type: integer
        format: int32
        enum:
          - Sunny
          - Cloudy
          - Rainy

weather3 produced Java code :

public enum TypeEnum {
    NUMBER_1(1),
    NUMBER_2(2),
    NUMBER_3(3);

    private Integer value;

    TypeEnum(Integer value) {
      this.value = value;
    }

    @Override
    @JsonValue
    public String toString() {
      return String.valueOf(value);
    }
  }

Is there any syntax for having custom names for each enum items?

weather3 caused exception for Swift (I guess not supported yet) :

Exception in thread "main" java.lang.RuntimeException: Could not process model 'weather3'
    at io.swagger.codegen.DefaultGenerator.generate(DefaultGenerator.java:244)
    at io.swagger.codegen.cmd.Generate.run(Generate.java:223)
    at io.swagger.codegen.SwaggerCodegen.main(SwaggerCodegen.java:36)
Caused by: java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
    at io.swagger.codegen.languages.SwiftCodegen.fromProperty(SwiftCodegen.java:331)
wing328 commented 8 years ago

For weather1 and weather4, I don't think it's valid as the enum is string but the type is integer.

For enum naming convention, is there any reference? The most common one I saw is adding the "Enum" suffix (e.g. StatusEnum).

kenjitayama commented 8 years ago

For weather1 and weather4, I don't think it's valid as the enum is string but the type is integer.

I agree. Tried them in case I could find out something.

For enum naming convention, is there any reference? The most common one I saw is adding the "Enum" suffix (e.g. StatusEnum).

Looks like I couldn't express my question correctly. Is there a way to get

public enum TypeEnum {
    Sunny(1),
    Cloudy(2),
    Rainy(3);

Instead of

public enum TypeEnum {
    NUMBER_1(1),
    NUMBER_2(2),
    NUMBER_3(3);

?

wing328 commented 8 years ago

Don't think we support that at the moment.

Should be mapping be done in the server side, which means the client will send the string "Sunny" and the server will map it to 1 (in database, etc)?

kenjitayama commented 8 years ago

Don't think we support that at the moment.

This was what I was looking for…, but thanks for sharing.

Should be mapping be done in the server side, which means the client will send the string "Sunny" and the server will map it to 1 (in database, etc)?

In my case, the client needs to send and retrieve 1 knowing that it means "Sunny". Maybe this kind of server API design is considered not good, but I need to stick with it. I guess the best that I can do is to describe them with description:, and write enums manually.

wing328 commented 8 years ago

@kenjitayama technically we can support it via vendor extension with code changes in how to handle the enum mapping.

kenjitayama commented 8 years ago

I see that the Swagger specs itself doesn't support this use case. I think the vendor extension could be something like this:

properties:
  type:
    type: integer
    format: int32
    enum:
      - 1
      - 2
      - 3
    x-enumNames:
      - Sunny
      - Cloudy
      - Rainy 

I saw swagger-codegen supporting a vendor extension before (x-swagger-router-controller) , so I recognize that it's position is not closed for supporting vendor extensions. It will be great if I can see this happen in the future. Maybe this is something that can go into Open API 3.0 specs?

wing328 commented 8 years ago

Feel free to suggest here: https://github.com/OAI/OpenAPI-Specification/issues

wing328 commented 8 years ago

2.2.1 has been released with some improvements in enum. Please give it a try.

kenjitayama commented 8 years ago

I'm currently not using swagger(nor any API description language), but I'm listening to updates :) I'd love to try if this feature gets supported.

ePaul commented 8 years ago

I think for better support (i.e. define name + value together) we need to wait for OpenAPI 3.0. https://github.com/OAI/OpenAPI-Specification/issues/681 seems to have some ideas on how this could be defined. If we have that, implementing it in Codegen seems quite straightforward.

martinmcwhorter commented 7 years ago

I have noticed that Enums are not properly generated in the Angular2 TypeScript Client. I will look at the code of that specific generator to see if it is a bug there.

paranoid945 commented 7 years ago

@kenjitayama @wing328

@Override
@JsonValue
public String toString() {
  return String.valueOf(value);
}

Did you guys noticed that the json value generated is type string instead of type integer, which is wrong by swagger spec?

ePaul commented 7 years ago

@paranoid945 could you please open a new issue about this? I fear it gets lost in this discussion, which is about supporting names for enum values.

paranoid945 commented 7 years ago

@ePaul I opened #5177 for this.

Skyfish1 commented 7 years ago

Is there also a way to have Enums with additional values

I have something like this in Java:

public enum MimeType { PDF("application/pdf"), PNG("image/png"), XML("text/xml"), HTML("text/html"), PKPASS("application/pkpass");

protected final String mediaTyp;

private MimeType(@NotNull String mediaType) {
    if(mediaType == null) {
        throw new IllegalArgumentException("Argument \'mediaType\' must not be \'null\'!");
    } else {
        this.mediaType = mediaType;
    }
}

public String getMediaType() {
    return this.mediaType;
}

}

craffael commented 7 years ago

I've implemented the x-enumNames approach suggested by @kenjitayama that passes the value of the x-enumNames list to the template: x-enumNames

Considering that even Version 3 of the Swagger OpenAPI Spec does not support something similar in the near future, I think it may be an option to add this "vendor extension" to swagger-codegen?

xiangyucao commented 6 years ago

Help! I think my problem is related to this. Here is my enum:

public enum JoinType
{
    Private = 0,
    ApprovalNeeded = 1,
    Auto = 2  
}

Any I use c.DescribeAllEnumsAsStrings(); So my interface looks like: "JoinType":{"enum":["Private","ApprovalNeeded","Auto"],"type":"string"}.

But the generated code start with enum 1, instead of 0? Why? C# default start with 0 instead of 1. Is there any way I can specify the start number?? Thanks!

vaishali-ntnx commented 6 years ago

Is there any plan to support this for Golang?

FearlessHyena commented 5 years ago

It's been a while since this was proposed. Any updates or plans for supporting this?

nasirvi commented 4 years ago

We are also facing the same issue for C#. @xiangyucao, did you find any solution for this?

xiangyucao commented 4 years ago

No, I didn't find anySent from my T-Mobile 4G LTE Device -------- 原始信息 --------发件人: Naresh Sirvi notifications@github.com 日期: 2020/2/11 上午1:56 (GMT-08:00) 收件人: swagger-api/swagger-codegen swagger-codegen@noreply.github.com 抄送: Shawn Cao xiangyucao@gmail.com, Mention mention@noreply.github.com 主题: Re: [swagger-api/swagger-codegen] Generate enums with integer values   assigned (#2690) We are also facing the same issue for C# @xiangyucao have you find any solution for this?

—You are receiving this because you were mentioned.Reply to this email directly, view it on GitHub, or unsubscribe. [ { "@context": "http://schema.org", "@type": "EmailMessage", "potentialAction": { "@type": "ViewAction", "target": "https://github.com/swagger-api/swagger-codegen/issues/2690?email_source=notifications\u0026email_token=ABYENNK7676TC6USIGOYIELRCJY4TA5CNFSM4CBYZFNKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOELLZVFY#issuecomment-584555159", "url": "https://github.com/swagger-api/swagger-codegen/issues/2690?email_source=notifications\u0026email_token=ABYENNK7676TC6USIGOYIELRCJY4TA5CNFSM4CBYZFNKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOELLZVFY#issuecomment-584555159", "name": "View Issue" }, "description": "View this Issue on GitHub", "publisher": { "@type": "Organization", "name": "GitHub", "url": "https://github.com" } } ]

fzyzcjy commented 4 years ago

Hi, what about dart/flutter support of enums? Thanks!

ArvindLakra commented 2 years ago

Hello,

Was it implemented in any update? I am also running into same issue. Want to define custom value for specific enum names.

Any plan to support this ?

Thanks, Arvind Lakra

jgarciadelanoceda commented 2 years ago

Same issue in C#. Reviewed the OpenApi generator of VS and if you set the extension x-enumNames the generator of VS writes the Enum with the correct values.

Good feature to have in Swagger-CodeGen too