Bug Report Checklist
Description
The issue: the current Crystal generator generates code with wrongly typed variables.
openapi-generator version
master
Generation Details
The story :
The current Crystal generator generates this code :
For example, to destroy bookmarks in bulk I can use this method :
# @param bookmark_request [Array(BookmarkRequest)]
def extras_bookmarks_bulk_destroy(bookmark_request : Array(BookmarkRequest))
which needs an array of BookmarkRequest :
module NetboxClient
# Extends the built-in ModelSerializer to enforce calling full_clean() on a copy of the associated instance during validation. (DRF does not do this by default; see https://github.com/encode/django-rest-framework/issues/3144)
class BookmarkRequest
include JSON::Serializable
include YAML::Serializable
# Required properties
@[JSON::Field(key: "object_type", type: String, nillable: false, emit_null: false)]
property object_type : String
@[JSON::Field(key: "object_id", type: Int64, nillable: false, emit_null: false)]
property object_id : Int64
@[JSON::Field(key: "user", type: BookmarkRequestUser, nillable: false, emit_null: false)]
property user : BookmarkRequestUser
In BookmarkRequest there is a field user of type BookmarkRequestUser :
BookmarkRequestUser is actually not a type but more a factory that builds the real type (BriefUserRequest or Int32) depending on the data passed to the build(data) method :
module NetboxClient
module BookmarkRequestUser
class SchemaMismatchError < Exception
end
# List of class defined in oneOf (OpenAPI v3)
def self.openapi_one_of
[
BriefUserRequest,
Int32,
]
end
def self.build(data)
# Go through the list of oneOf items and attempt to identify the appropriate one.
# Note:
# - We do not attempt to check whether exactly one item matches.
# - No advanced validation of types in some cases (e.g. "x: { type: string }" will happily match { x: 123 })
# due to the way the deserialization is made in the base_object template (it just casts without verifying).
# - TODO: scalar values are de facto behaving as if they were nullable.
# - TODO: logging when debugging is set.
openapi_one_of.each do |klass|
begin
# next if klass == :AnyType # "nullable: true"
typed_data = find_and_cast_into_type(klass, data)
return typed_data if typed_data
rescue # rescue all errors so we keep iterating even if the current item lookup raises
end
end
# openapi_one_of.includes?(:AnyType) ? data : nil
nil
end
One of the real type is BriefUserRequest which take a single string username :
module NetboxClient
# Extends the built-in ModelSerializer to enforce calling full_clean() on a copy of the associated instance during validation. (DRF does not do this by default; see https://github.com/encode/django-rest-framework/issues/3144)
class BriefUserRequest
include JSON::Serializable
include YAML::Serializable
# Required properties
# Requis. 150 caractères maximum. Uniquement des lettres, nombres et les caractères « @ », « . », « + », « - » et « _ ».
@[JSON::Field(key: "username", type: String, nillable: false, emit_null: false)]
property username : String
So let's try to delete some bookmarks :
def self.delete_bookmarks
# Recall:
# class BookmarkRequest
# @[JSON::Field(key: "user", type: BookmarkRequestUser, nillable: false, emit_null: false)]
# property user : BookmarkRequestUser
user = NetboxClient::BookmarkRequestUser.build(NetboxClient::RecursiveHash.new({"username" => "foo"}))
object = NetboxClient::BookmarkRequest.new(object_type: "Device", object_id: 42.to_i64, user: user)
puts YAML.dump(object)
end
But because the final type NetboxClient::BriefUserRequest does not match with NetboxClient::BookmarkRequestUser it doesn't compile :
In src/netbox_extractor/controllers/test_api.cr:39:95
39 | object = NetboxClient::BookmarkRequest.new(object_type: "Device", object_id: 42.to_i64, user: user)
^
Error: expected argument 'user' to 'NetboxClient::BookmarkRequest.new' to be NetboxClient::BookmarkRequestUser, not (Int32 | NetboxClient::BriefUserRequest | Nil)
Suggest a fix
To solve this I'd like to change model definition from :
module NetboxClient
# Extends the built-in ModelSerializer to enforce calling full_clean() on a copy of the associated instance during validation. (DRF does not do this by default; see https://github.com/encode/django-rest-framework/issues/3144)
class BookmarkRequest
include JSON::Serializable
include YAML::Serializable
# Required properties
@[JSON::Field(key: "object_type", type: String, nillable: false, emit_null: false)]
property object_type : String
@[JSON::Field(key: "object_id", type: Int64, nillable: false, emit_null: false)]
property object_id : Int64
@[JSON::Field(key: "user", type: BookmarkRequestUser, nillable: false, emit_null: false)]
property user : BookmarkRequestUser
to
module NetboxClient
# Extends the built-in ModelSerializer to enforce calling full_clean() on a copy of the associated instance during validation. (DRF does not do this by default; see https://github.com/encode/django-rest-framework/issues/3144)
class BookmarkRequest
include JSON::Serializable
include YAML::Serializable
# Required properties
@[JSON::Field(key: "object_type", type: String, nillable: false, emit_null: false)]
property object_type : String
@[JSON::Field(key: "object_id", type: Int64, nillable: false, emit_null: false)]
property object_id : Int64
@[JSON::Field(key: "user", type: BriefUserRequest | Int32, nillable: false, emit_null: false)] # <= here
property user : BriefUserRequest | Int32 # <= and here
but I don't know if it's feasible.
or make BriefUserRequest a generic? I don't know. won't work
Bug Report Checklist
Description
The issue: the current Crystal generator generates code with wrongly typed variables.
openapi-generator version
master
Generation Details
The story :
The current Crystal generator generates this code :
For example, to destroy bookmarks in bulk I can use this method :
which needs an array of
BookmarkRequest:In
BookmarkRequestthere is a fielduserof typeBookmarkRequestUser:BookmarkRequestUseris actually not a type but more a factory that builds the real type (BriefUserRequestorInt32) depending on the data passed to thebuild(data)method :One of the real type is
BriefUserRequestwhich take a single stringusername:So let's try to delete some bookmarks :
But because the final type
NetboxClient::BriefUserRequestdoes not match withNetboxClient::BookmarkRequestUserit doesn't compile :Suggest a fix
To solve this I'd like to change model definition from :
to
but I don't know if it's feasible.
or makewon't workBriefUserRequesta generic? I don't know.