admin-shell-io / aas-specs-api

Repository of the Asset Administration Shell Specification DTA-01002 API
https://admin-shell-io.github.io/aas-specs-antora/index/home/index.html
Creative Commons Attribution 4.0 International
12 stars 5 forks source link

Result Objects are not Type-Safe #50

Closed sebbader-sap closed 1 year ago

sebbader-sap commented 1 year ago

What?

We're trying to improve the compatibility of assets between different organisations and technologies. Thus we should try to create APIs, that can be realized in at least the majority technologies. The strategy of modifying result structures via query parameters results in bad implementations. The majority of implementation frameworks expects a polymorph result. Typesafety is a general requirement from a technology independent view. An endpoint, that returns in one case a Submodel, in the next a Reference or a simple, idShort-Name based map, has as return type "Object"/"Any" - a clear anti-pattern in most environments.

An URL Path like /shells/<id>/submodels/<id>/submodel/metadata or /shells/<id>/submodels/<id>/submodel/reference result in very much clearer interfaces, that can be implemented straight in most technologies - with typesafety. An interfaces specification, that can't be expressed in RDF / swagger, most probably doesn't follow best practices guides.

How?

Switch to explicit endpoints, that accept/produce structures, that can be documents in rdf / swagger.

This issue has been raised as IDTA_Repo_4.

sebbader-sap commented 1 year ago

OData for instance promotes:

noheton commented 1 year ago

I wholeheartedly agree on: "The strategy of modifying result structures via query parameters results in bad implementations." If we want to keep the current API structure regarding modifiers - maybe, we are approaching again on Polymorphism / Discriminator. see https://swagger.io/docs/specification/data-models/inheritance-and-polymorphism/ Still, I think this would keep (and encourage) this this bad practice.

From a technical perspective I understand the OData approach as predefined (read standardized) general endpoints for different "response modifications".

Overall, I would rather be in favor of an extensive redesign/refactoring (of the afflicted endpoints) than further building on a fragile (=non-type-safe) solution.

sebbader-sap commented 1 year ago

I try a new approach with a better terminology (Service-Specification vs. API vs. API Operation) and relying on media types instead of Serialisation Parameters: https://app.swaggerhub.com/apis/sebbader/AssetAdministrationShell-ServiceSpecification/V3.0 @noheton @aorzelskiGH @danielporta please have a look before next Tuesday.

noheton commented 1 year ago

Thanks for your experiment.

In my opinion a swagger file cannot be a service-specification, at least I would consider this definition misleading:

Quoting from OAS 3 Spec^1:

OpenAPI Document A self-contained or composite resource which defines or describes an API or elements of an API. The OpenAPI document MUST contain at least one paths field, a components field or a webhooks field. An OpenAPI document uses and conforms to the OpenAPI Specification.

I will try to put down my personal understanding of these elements just to find out where our opinions diverge:

API Operation:

API:

Service specification:

Sidenote: Is this the right issue for this topic?

sebbader-sap commented 1 year ago

Hi @noheton,

there are a few things coming together now.

  1. The aspect I wanted to highlight, which is in scope of this issue, are the different content-types in https://app.swaggerhub.com/apis/sebbader/AssetAdministrationShell-ServiceSpecification/V3.0#/Asset%20Administration%20Shell%20API/GetAssetAdministrationShell I am proposing yet another alternative for the type-safety problem: Currently: GET https://example.org/aas?content?meta

Proposal 1: GET https://example.org/aas/$meta

Proposal 2 (in the new swagger file):

GET https://example.org/aas

Content-Type: application/json;content=meta
sebbader-sap commented 1 year ago
  1. The terminology from OpenApi vs. the Part 2 wording:

API Operation: (in AAS context, Part 2): Protocol-agnostic Definition of operations on/with AAS

No, I see an API and API Operation as protocol-specific. Interface or Interface Operation present the protocol-agnostic part.

Is an OpenApi file the right document to define a Service-Specification? Not sure, but I see several advantages:

  1. I want to see it as a structural element in the form of: You want to implement a Repository Service? Great, then implement all APIs of the Repository Service-Specification OpenApi file.
  2. You want only a subset of possible Repository functions? Great, then implement all APIs of the Repository Service-Specification Basic-Profile OpenApi file.
  3. One API can then be defined by all API Operations which share the same tag (Asset Administration Shell API in the linked file).

The following list are examples (non-exhaustive) for contained information in a "service-specification": type of service (e.g. Registry, AASServer, SubmodelHost, a combination) supported model-versions supported operations (aggregated in profiles, or individual operation list) maybe: information on the service provider (to be extended)

I think I have a different opinion but I am not sure how to express it. Let's talk about it next Tuesday. I think we are not too far away from each other...

sebbader-sap commented 1 year ago

Sidenote: Is this the right issue for this topic?

Not really, or? At least not for the second topic :-). But now we have a vivid offline discussion, so let's just keep it here. The repo is still private, so let's make use of it.

noheton commented 1 year ago

Is an OpenApi file the right document to define a Service-Specification? Not sure, but I see several advantages:

  1. I want to see it as a structural element in the form of: You want to implement a Repository Service? Great, then implement all APIs of the Repository Service-Specification OpenApi file.
  2. You want only a subset of possible Repository functions? Great, then implement all APIs of the Repository Service-Specification Basic-Profile OpenApi file.
  3. One API can then be defined by all API Operations which share the same tag (Asset Administration Shell API in the linked file).

I can see value in this approach (big fan of code generation :) ) - great boilerplate and very useful tool for quickly getting started implementing services, but i don't see a "normative" aspect there.

Another question i am currently asking myself: if someone has a generic AAS-Server REST-client (which would usually be not "service specification aware") how should the server respond if the client tries to call a not-implemented method? I think a specific error should be thrown than a HTTP Status code like 404/405.

noheton commented 1 year ago

Quick idea: Using one OpenApi specification, we could annotate operations with Tags. This would enable consistency and easier maintenance when we define additional endpoints.

danielporta commented 1 year ago

Sticking to the inital topic, I definitely prefer proposal 1. GET https://example.org/aas/$meta

sebbader-sap commented 1 year ago

Additional remark from Basyx:   /shells/_metadata /shells/_reference /shells/{aasIdentifier}/submodels/{submodelIdentifier}/_metadata /shells/{aasIdentifier}/submodels/{submodelIdentifier}/_reference

Which is permitted by https://www.rfc-editor.org/rfc/rfc1738 :

httpurl        = "http://" hostport [ "/" hpath [ "?" search ]] 
hpath          = hsegment *[ "/" hsegment ] 
hsegment       = *[ uchar | ";" | ":" | "@" | "&" | "=" ]
uchar          = unreserved | escape
unreserved     = alpha | digit | safe | extra 
safe           = "$" | "-" | "_" | "." | "+"

RFC 1738: Uniform Resource Locators (URL)

sebbader-sap commented 1 year ago

Continuing with Proposal 1 (the one with .../$metadata paths):

Repository_Service-Specification shows how imagine this approach. Again, a lot of things are mixed, so be aware that:

There is also a first attempt for a profile: Repository-BasicProfile is more or less the Repository_Service-Specification minus Pagination minus Levels minus Content suffix paths

sebbader-sap commented 1 year ago

Same story for the AAS API:

And the last is the Submodel API, same pattern as for the AAS API.

sebbader-sap commented 1 year ago

Solution ready with the new ServiceSpecification concept and the respective OpenAPI files.