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

Generate RESTful APIs from spec #3090

Open
dblock opened this issue Apr 27, 2022 · 8 comments
Open

Generate RESTful APIs from spec #3090

dblock opened this issue Apr 27, 2022 · 8 comments
Labels
Build Libraries & Interfaces Clients Clients within the Core repository such as High level Rest client and low level client enhancement Enhancement or improvement to existing feature or request feature New feature or request help wanted Extra attention is needed

Comments

@dblock
Copy link
Member

dblock commented Apr 27, 2022

Is your feature request related to a problem? Please describe.

Coming from opensearch-project/opensearch-api-specification#30, RESTful APIs are hand-rolled, making it difficult to inspect the available routes, required or optional parameters.

Describe the solution you'd like
Use https://github.com/opensearch-project/opensearch-api-specification to generate code in OpenSearch.

History
In this issue we discussed an approach that either starts with code that can be inspected/reflected, or starts with a spec, but not both. We proposed using https://github.com/opensearch-project/opensearch-api-specification to generate code in OpenSearch, vs. usng OpenSearch to export the spec in https://github.com/opensearch-project/opensearch-api-specification.

@dblock dblock added enhancement Enhancement or improvement to existing feature or request untriaged labels Apr 27, 2022
@dblock dblock changed the title Enable reflection of RESTful API Enable reflection of RESTful API or generate RESTful APIs from spec Apr 27, 2022
@dblock
Copy link
Member Author

dblock commented Apr 27, 2022

@sachetalva I believe you've looked at what effort it would take to enable "use OpenSearch to export the spec"?

@nknize
Copy link
Collaborator

nknize commented Apr 27, 2022

💯 We really need help in this area. We can version the REST APIs all we want to help with client compatibility but keeping the clients NSync w/ the API is another matter. Would love to see someone from the community step up and help here as well!

@nknize nknize added the help wanted Extra attention is needed label Apr 27, 2022
@sachetalva
Copy link

Hi @dblock and @nknize, yes ideally it would be good if we can generate the OpenSearch rest api handlers auto generated from the opensearch-api-specification. However currently there is no direct solution to achieve this.
One of the possible approaches currently is to generate Java POJO classes from the Smithy/OpenAPI models and use these to update the request / response handling in OpenSearch. This would ensure that the api-specification is always in sync with the OpenSearch code. However, we have not explored this approach yet and would need some further research.
To be able to achieve this we would need the smithy models for all the APIs as a pre-req. Currently we are working on setting up api models for the basic CRUD OpenSearch APIs. We are also setting up a CI framework which will help to automatically validate all model files, which will help in faster development and validation of the new smithy model files.

@dblock
Copy link
Member Author

dblock commented Apr 28, 2022

@sachetalva You're proposing a spec -> code path. I am saying there's probably also a code -> spec path.

@sachetalva
Copy link

Code -> spec should also be possible but this has not been explored yet. From initial investigation there is no direct approach available to generate Smithy models from code. Custom annotations could be created around the request and response handling code in OpenSearch to declare the request and response body parameters. However we would have an additional overhead to maintain code which translates the structures defined in annotations / code to corresponding Smithy structures and data types.

@reta
Copy link
Collaborator

reta commented May 3, 2022

@dblock a few thoughts on that, as far as I can tell, the Opensearch core does NOT have a formal, structured models for APIs, in many cases it is buried behind ToXContent implementations, fe:

    @Override
    public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
        builder.startObject(Fields.JVM);
        builder.field(Fields.TIMESTAMP, timestamp);
        builder.humanReadableField(Fields.UPTIME_IN_MILLIS, Fields.UPTIME, new TimeValue(uptime));

        ...
    }

Having formal models (POJOs) would have made specs generation easier but it is huge amount of work. However, there are different approaches out there which we may loot at. For example, Spring REST Docs [1] relies on auto-generated snippets produced with test scaffolding (in this case, Spring MVC Test [2]). The main idea here is to capture API calls + requests + responses in tests and publish them as documentation / specification (we do not need to use these great projects as-is, but borrow the idea). Something to explore, wdyt?

The reverse spec -> code path would be the best option (in my opinion) but still, it very likely would require to replace free style ToXContent transformations with formal (generated) models.

[1] https://spring.io/projects/spring-restdocs#overview
[2] https://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle#spring-mvc-test-framework

@rursprung
Copy link
Contributor

i would strongly suggest the spec -> code path: this allows designing the API first, leading to cleaner APIs for consumers rather than starting it with a technology-specific API which just happens to carry some annotations turning it into something which you can call over HTTP (and might not follow any proper RESTful guidelines).

yes, the initial move will be quite a bit of effort, but it'll ultimately pay off in the long run. and probably it doesn't have to be done as a big-bang approach but can instead be done endpoint by endpoint.

as far as i can see smithy specs can be converted to OpenAPI specs and these in turn can be used to generate both client and server stubs e.g. using the org.openapi.generator gradle plugin.

what will definitely not work mid- to long-term is just trying to maintain the specs manually based on changes to the code, this is guaranteed to diverge and is just a waste of time for everyone (maintainers trying to constantly keep it aligned and consumers trying to use it just to learn that there was yet another difference between spec and real API).

@dblock dblock changed the title Enable reflection of RESTful API or generate RESTful APIs from spec Generate RESTful APIs from spec May 5, 2022
@dblock
Copy link
Member Author

dblock commented May 5, 2022

It's pretty clear that most people recommend generating code from spec. I agree. I edited this issue to reflect that proposal, leaving history to how we came here.

If anyone wants to take a stab at replacing any part of the code in OpenSearch by code generated from https://github.com/opensearch-project/opensearch-api-specification, you'll be my hero. Re: OpenAPI we need a pipeline that automatically publishes the Smithy IDL in that format, I opened opensearch-project/opensearch-api-specification#34.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Build Libraries & Interfaces Clients Clients within the Core repository such as High level Rest client and low level client enhancement Enhancement or improvement to existing feature or request feature New feature or request help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

7 participants