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

Support of com.sap.vocabularies.Common.v1.ValueList annotation planned? #13

Closed
ttrapp opened this issue Jun 15, 2018 · 7 comments
Closed

Comments

@ttrapp
Copy link

ttrapp commented Jun 15, 2018

IMHO one of the biggest issue with OData services V2 are missing enumeration types. This makes interfaces very hard to use. Therefore I would like to ask, whether a support of the com.sap.vocabularies.Common.v1.ValueList annotation is planned. Maybe those values could be transformed to OData V4 enumeration type and exported as Open API enum.

@ralfhandl
Copy link
Contributor

Common.ValueList is sort of a glorified hyperlink to an entity set (of the same service) that can be queried at run-time for a list of allowed values. It covers both static and dynamic value lists and makes the API rather easy to use if you "explore" it with a Fiori Elements UI 😉 However it does not translate well into OpenAPI enumeration values which are static by nature and need to be known at design-time.

What would translate well into OpenAPI enumeration values and can be used with V2 services is the annotation Validation.AllowedValues. However OpenAPI currently does not allow having descriptions for enumeration values, see OAI/OpenAPI-Specification#348 and OAI/OpenAPI-Specification#681, which somewhat reduces the value of having a list of values: Rating:{enum:[1,2,3]} - is 1 better than 3 or worse? Which is why I haven't considered this annotation yet in the transformation.

@ttrapp
Copy link
Author

ttrapp commented Jul 3, 2018

I would like to try it out. Can you point me to an example in OData V2?

Yes, descriptions are not specified in OpenAPI. I think commentaries would help.

@ralfhandl
Copy link
Contributor

ralfhandl commented Jul 3, 2018

Attached is a somewhat silly metadata example with two entity sets, one for flights, one for currencies. The currencies set is the value list for the currency property in the flights entity set.

However this is not translated into OpenAPI at all as I have no idea how to represent it. The actual currencies are only known at run-time, and the list of funny currencies in my test system will most likely differ from the list of real currencies in your production system even though the API structure can be identical.

zrha_flight_cds.zip

I'm curious where you want to go with this.

@ttrapp
Copy link
Author

ttrapp commented Jul 3, 2018

Thank you, this is exactly what I have in mind. For the certain element you define in the collection path the entityset which is probably a CDS view containing currencies. I could be translated into something like that:

currency:
type: string
enum:
- EUR # Euro
- USD # US Dollar

Why I find it reasonable?

1.) As you told every SAP system might have a different customizing. So two services have different types of interface contracts. One service might accept EUR and USD, another one only EUR f.e. This means that the client applications that use the OData services in the landscape of your test system behave differently than the ones in the landscape of your production system. The documentation would make this behavior transparent. It would be even an improvement if above documentation would be included as comment.
2.) Every SAP system has a change management. A change in customizing is the result of a change process and afterwards the system behavior is different. So after a change the documentation should be regenerated.

IMHO in a software solution with lots of enumeration types defined by customzing above solution is the only way to make it possible to use the services.

I am well aware that the change is not trivial since one has to call the entityset and include the XML file into the transformation.

@ralfhandl
Copy link
Contributor

The scope of this project is transforming $metadata into OpenAPI JSON. Data access is definitely out of scope.

Even if I were that ambitious: how should I distinguish a "currencies" value list from a "customers" value list? From an OData perspective they are indistinguishable, both are entity sets. And while I wish to have millions of customers, I don't wish to have their IDs and names in an OpenAPI description 😅

From an OData perspective the ValueList annotation in $metadata is sufficient: it describes that at run-time you can get a list of allowed values for a certain property from some other entity set in the same service.

@ttrapp
Copy link
Author

ttrapp commented Jul 3, 2018

I don't think it will be a problem to distinguish between master data and customizing since the metadata are within the data dictionary.

But Ok, I will try to solve it on my own. Can you give me a hint in which XSLT template I should enhance?

@ralfhandl
Copy link
Contributor

ralfhandl commented Jul 3, 2018

For a start you need a preprocessing step that analyzes $metadata and then fires GET requests for all value-list entity sets.

Which is tricky, because $metadata doesn’t tell you anything about the underlying data source - intentionally, because even SAP has OData services not implemented in ABAP ;-) So you need to invent your own mechanism for identifying/annotating entity sets that you want to “flatten” out into the OpenAPI description.

Then you’d have to figure out how to access multiple input files from XSLT - should be possible, but I’ve never tried it.

A future obstacle is that you might want your extractor to work with V2 and V4 services and their different formats: Atom or JSON with V2, mostly only JSON with V4, so you need to harmonize that, likely into your own XML dialect if you want to stick with XSLT.

Which is another sore point for me: XSLT was the obvious choice for simple “one XML file in, one JSON text out“. As of now the transformation is no longer simple, and having multiple input files violates the last of the initial boundary conditions. In short: better start from scratch with a language more appropriate for this larger problem. Given that all possible input files ($metadata, V2 data, V4 data) is now available in JSON, Node.js and JavaScript seem to be the obvious choice.

@ttrapp ttrapp closed this as completed Jul 5, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants