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.86k stars 6.02k forks source link

[Swift4] Model initializer with required properties only #8365

Open sadanro100 opened 6 years ago

sadanro100 commented 6 years ago

To illustrate my problem I'm going to use the Client model available below. In our Client model, there are 26 properties, where only 3 are required (non-optional).

Client.swift.zip

In swagger-codegen-2.4.0 models are generated with no initializers, when a model has only optional properties, I'm able to initialize it with no arguments (so Client() is possible), however, when there's at least one required property the only initalizer available forces me to pass values to the required arguments and nil to the rest, as follows:

let client = Client(cpf: clientCPF, name: clientName, email: clientEmail, alternateEmail: nil, motherName: nil, birthDate: nil, maritalStatus: nil, maritalPartner: nil, identityDocuments: nil, personalPhones: nil, residentialAddress: nil, professionalData: nil, birthCity: nil, birthState: nil, graduation: nil, fatherName: nil, nationality: nil, residenceType: nil, gender: nil, clientReferences: nil, clientAssets: nil, residenceLiveYears: nil, consultCreditDataAuthorization: nil, proxy: nil, paymentOption: nil, debitAccount: nil)

I'd like to have an initializer with only required properties, like:

let client = Client(cpf: clientCPF, name: clientName, email: clientEmail)

Being forced to pass nil to all optional properties when initializing a model when I only need a couple of properties looks really bad.

Is it possible to have another initializer that takes only required properties?

swagger-codegen-2.4.0

java -jar ~/Documents/projects/swagger/swagger-codegen-2.4.0/modules/swagger-codegen-cli/target/swagger-codegen-cli.jar generate -i /Users/me/Downloads/swagger.json -l swift4 -o /Users/me/Downloads/swagger-output

deanWombourne commented 4 years ago

Another option here is to add = nil to all optional properties (which would require generating an explicit init method for the model struct) but would allow you to choose all/any/none of the optional properties when you were calling init.

i.e.

struct Client {
    ...
    let email: String
    let alternateEmail: String?
    ...

    /// Generate an explicit init with default values for optionals.
    init(..., email: String, alternateEmail: String? = nil, ...) {
    }
}
sadanro100 commented 4 years ago

We ended up doing that... we customized the moustache template and generate the client code using the template parameter

deanWombourne commented 4 years ago

FYI: I've raised this as an issue on the swagger 3 template repo as well: https://github.com/swagger-api/swagger-codegen-generators/issues/467

sadanro100 commented 4 years ago

We're no longer using codegen, we moved on to openAPI, we then modified its Models moustache template

deanWombourne commented 4 years ago

Yea, that's a much better idea, I've just done the same with far more success than the swagger 3 branch in this repo :)

By any chance have you looked at other alternatives (i.e. https://github.com/yonaskolb/SwagGen)? I'm looking around to refresh our tools and would be interested in other people's opinions on what works / doesn't - if you have time, obvs!

sadanro100 commented 4 years ago

I did have a look at was available two years ago when I started at the job where I'm right now, at the time, codegen seemed to be the best option for our iOS clients since other clients (web, android...) were already using it. Now that I understand exactly how codegen works, I'm sure that was the right choice, specially because it uses Alamofire behind and its architecture for intercepting requests, retrying failed requests, handling errors and so on is pretty clear and straighforward.