Haskell-OpenAPI-Code-Generator / Haskell-OpenAPI-Client-Code-Generator

Generate Haskell client code from an OpenAPI 3 specification
47 stars 19 forks source link

GetContactsResponseError "Error in $.objects[0].academicTitle: parsing Text failed, expected String, but encountered Null" #115

Closed schoettl closed 1 month ago

schoettl commented 1 month ago

Not sure what's the problem here. I get this response error in my sevDesk API client (generated by latest Haskell-OpenAPI-Code-Generator):

GetContactsResponseError "Error in $.objects[0].academicTitle: parsing Text failed, expected String, but encountered Null"

The response JSON list items all contain the field academicTitle with value null. Yet the API client seems to require it although it's a Maybe. I'm also a bit confused by the error message mentioning Text and String.

From the generated model type:

-- | Defines the object schema located at @components.schemas.Model_ContactResponse@ in the specification.
-- 
-- Contact model
data Model_ContactResponse = Model_ContactResponse {
  -- | academicTitle: A academic title for the contact.
  -- Not to be used for organizations.
  model_ContactResponseAcademicTitle :: (GHC.Maybe.Maybe Data.Text.Internal.Text)
  …

The FromJSON instance contains (obj Data.Aeson.Types.FromJSON..:! "academicTitle"), maybe this should use (.:?) instead? But I also tried that and get the same error.

{
  "objects": [
    {
      "id": "84510735",
      "objectName": "Contact",
      "description": null,
      "academicTitle": null,
       …

Any hints where this could come from are appreciated!

NorfairKing commented 1 month ago

Maybe and Nullable are not the same. Maybe is for optional fields and Nullable are for fields that can be null

schoettl commented 1 month ago

Thanks for the answer! Right, I now understand the difference but somehow the generator creates the Model_ContactResponse type above that does not contain the Nullable.

On the other hand, it also generates a Model_Contact type that does contain Nullable. Maybe it's a kind of name clash where it tries to parse into the wrong type?

The source spec is for that endpoint is:

  …
  /Contact:
    get:
      tags:
        - Contact
      summary: Retrieve contacts
      description: "There are a multitude of parameter which can be used to filter.<br>\r\n     A few of them are attached but\r\n     for a complete list please check out <a href='https://api.sevdesk.de/#section/How-to-filter-for-certain-contacts'>this</a> list"
      operationId: getContacts
      parameters:
        …
      responses:
        '200':
          description: Successful operation
          content:
            application/json:
              schema:
                properties:
                  objects:
                    type: array
                    items:
                      $ref: '#/components/schemas/Model_ContactResponse'
                type: object
…

and the schema is defined as:

    Model_ContactResponse:
      title: Contact model
      description: Contact model
      properties:
        …
        academicTitle:
          description: |-
            A academic title for the contact.
            Not to be used for organizations.
          type: string
          readOnly: true
…
schoettl commented 1 month ago

I now limited the code generation with --operation-to-generate getContacts.

Might it be a bug that $ref-linked schemas have no Nullable in the generated type?

NorfairKing commented 1 month ago

No this looks correct to me. There's no nullable in the schema anywhere..

schoettl commented 1 month ago

Oh! I wasn't aware that OpenAPI spec requires that null is explicitly allowed. For reference: https://stackoverflow.com/a/48114322/999007

So it is an error in the API specification. When I add the line nullable: true in the yaml specification for the field academicTitle, the error goes away.

Thanks for the help!