Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FEATURE] Consider annotations in imported API specifications #471

Open
MarvinWeitz opened this issue Jan 22, 2025 · 3 comments
Open

[FEATURE] Consider annotations in imported API specifications #471

MarvinWeitz opened this issue Jan 22, 2025 · 3 comments
Labels
feature request New feature or request new

Comments

@MarvinWeitz
Copy link

Description

Im currently using an API to get object children from the SAP Document Management Service.

I imported the OpenAPI resources into my project via cds import <path/to/file> --as cds. Now, the specification (and also the object returned by an API call) includes object keys with special characters, e.g. cmis:objectId. This is converted by cds import to cmis_objectId, which is also used as a basis by cds-typer. This results in wrong intellisense.

The generated API .cds file include some @openai annotations with the correct name though. In the example case:

// GetChildrenApi.cds

...
type Get.Children_types.object {
  objects                         : many {
    object                        : {
      properties                  : {
          @openapi.name      : 'cmis:objectId'
        cmis_objectId             : {
          @Core.Example.$Type: 'Core.PrimitiveExampleValue'
          @Core.Example.Value: 'cmis:objectId'
          id                      :      String;
...

So there is the "correct" information present. It would be great if cds-typer would provide these openapi names instead of the wrongfully converted ones.

Suggested Solution

Use the correct API names indicated by the annotations.

I must say I'm unsure if it must be the case to generate two sets of types here. I haven't had a use case yet, where I used the names in e.g. cds entities. It could be the case, that the cds types themselves would be wrongly generated (the real problem would be the poorly chosen names in the api) or that the cds types are expected as generated. In the latter case two sets of types are needed.

Alternatives

The only alternative I see here is to create the types individually, which would counteract the purpose of cds-typer...

Additional Context

No response

@MarvinWeitz MarvinWeitz added feature request New feature or request new labels Jan 22, 2025
@daogrady
Copy link
Contributor

Hi Marvin,

thank you for bringing this up.
I just checked the CSN that is generated when loading the model you showed above:

{
  definitions: {
    'Get.Children_types.object': {
      kind: 'type',
      elements: {
        objects: {
          items: {
            elements: {
              object: {
                elements: {
                  properties: {
                    elements: {
                      cmis_objectId: {
                        '@openapi.name': 'cmis:objectId',
                        elements: [Object: null prototype]
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  meta: { creator: 'CDS Compiler v5.4.2', flavor: 'inferred' },
  '$version': '2.0'
}

So the property in question is indeed cmis_objectId at runtime. If we lied to the user and led them to believe they could do

this.on('READ', object, ({data}) => {
  data['cmis:objectId']
})

then they'd be confronted with runtime errors. The intellisense is therefore correct.

Best,
Daniel

@MarvinWeitz
Copy link
Author

MarvinWeitz commented Jan 27, 2025

Thank you for checking. What you wrote is true and is also my point why it might be necessary to create two individual types. Even though the CSN does contain cmis_objectId at runtime, the expected types of the CMIS service is still cmis:objectId.
As it is explained here, the request to a remote service must be forwarded in the event handler. And this is where the mismatch occurs: The CSN expects and uses the generated properties (cmis_objectId), while the underlying service expects cmis:objectId in its api call when forwarding the request.

This can also be seen in the case I described in the original message. When calling the API, the remote service does indeed return cmis:objectId.
Image

A workaround for this would be to use the openapi-generator with which the correct return type is exposed.

@daogrady daogrady added the keepalive Will not be closed by Stale bot label Jan 27, 2025
@daogrady
Copy link
Contributor

Hi Marvin,

we discussed your suggestion and came to the conclusion that this is not doable as of today.
There is no set of well-known annotations specifying a "real" name, we could use to determine when a property name should be overruled by an annotation (it's @openapi.name in your case, but could be any other annotation when using another importer/ source).
The article you linked also points out that these kinds of mappings should be made explicit via another projection. Your situation seems to be a bit different, as you are already importing CSV files, but can you check if you can incorporate the explicit projection anyway?

Best,
Daniel

@daogrady daogrady removed the keepalive Will not be closed by Stale bot label Feb 5, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature request New feature or request new
Projects
None yet
Development

No branches or pull requests

2 participants