Azure / autorest.java

Extension for AutoRest (https://github.com/Azure/autorest) that generates Java code
MIT License
33 stars 82 forks source link

How to modify method parameter in the generated code? #2847

Closed danielszaniszlo closed 4 months ago

danielszaniszlo commented 4 months ago

I have a generated method code that I need to modify due to a compilation error. The current method, listJobs(String continuationToken), uses continuationToken as an input parameter, but the return value also includes a continuationToken. Is there a way to consistently change the input parameter to nextToken?

The generated method looks like this:

    public PagedFlux<DeidentificationJob> listJobs(String continuationToken) {
        // Generated convenience method for listJobs
        RequestOptions requestOptions = new RequestOptions();
        if (continuationToken != null) {
            requestOptions.addQueryParam("continuationToken", continuationToken, false);
        }
        PagedFlux<BinaryData> pagedFluxResponse = listJobs(requestOptions);
        return PagedFlux.create(() -> (continuationToken, pageSize) -> {
            Flux<PagedResponse<BinaryData>> flux = (continuationToken == null)
                ? pagedFluxResponse.byPage().take(1)
                : pagedFluxResponse.byPage(continuationToken).take(1);
            return flux
                .map(pagedResponse -> new PagedResponseBase<Void, DeidentificationJob>(pagedResponse.getRequest(),
                    pagedResponse.getStatusCode(), pagedResponse.getHeaders(),
                    pagedResponse.getValue()
                        .stream()
                        .map(protocolMethodData -> protocolMethodData.toObject(DeidentificationJob.class))
                        .collect(Collectors.toList()),
                    pagedResponse.getContinuationToken(), null));
        });
    }

The expected output would be :

    public PagedFlux<DeidentificationJob> listJobs(String nextToken) {
        // Generated convenience method for listJobs
        RequestOptions requestOptions = new RequestOptions();
        if (continuationToken != null) {
            requestOptions.addQueryParam("continuationToken", nextToken, false);
        }
        PagedFlux<BinaryData> pagedFluxResponse = listJobs(requestOptions);
        return PagedFlux.create(() -> (continuationToken, pageSize) -> {
            Flux<PagedResponse<BinaryData>> flux = (continuationToken == null)
                ? pagedFluxResponse.byPage().take(1)
                : pagedFluxResponse.byPage(continuationToken).take(1);
            return flux
                .map(pagedResponse -> new PagedResponseBase<Void, DeidentificationJob>(pagedResponse.getRequest(),
                    pagedResponse.getStatusCode(), pagedResponse.getHeaders(),
                    pagedResponse.getValue()
                        .stream()
                        .map(protocolMethodData -> protocolMethodData.toObject(DeidentificationJob.class))
                        .collect(Collectors.toList()),
                    pagedResponse.getContinuationToken(), null));
        });
    }

I tried using azure-autorest-customization, but it didn't help. There is no option to consistently "replace" a variable within the function. While I can rename the function and replace the input parameters of it, the variable within the method body remains unchanged. I can only update the entire body.

alzimmermsft commented 4 months ago

Hi @danielszaniszlo I made a change to use a more unique hardcoded name in this area of code generation. Once that is released updating to that version of Autorest / TypeSpec should resolve this problem. In the meantime, if possible, I'd just recommend editing this code manually after code generation to resolve the compilation problem.

weidongxu-microsoft commented 4 months ago

Thanks Alan for the fix.

Hi @danielszaniszlo

Below is only a suggestion:

Azure SDK typically does not expose a listJobs(String nextToken) with the continuation token. It is almost impossible for user to make that continuation token by themselves. The token is usually from a paged response of the List itself (which is included in this listJob pageable API). Therefore, usually SDK API would just be listJobs().

User would do e.g.

// process by page
listJobs().streamByPage().forEach(page -> {
  // process each page as page.getValue()
});
// just fine a value in responses
listJobs().stream().findFirst(...);

or something like this, to consume the paged responses.

One may want to either not have this continuationToken query param in Swagger, or use directive to remove this query param in swagger/readme.md