Search code examples
kotlinspring-webfluxspring-restdocs

Adding path to base url in Spring Rest Docs?


I have following configuration to use with Rest Docs:

webTestClient = buildWebClient().mutate()
  .filter(documentationConfiguration(restDocumentation))
  .baseUrl("https://api.my-domain.com/")
  .build()

In my case I use path prefix to my service - service/foo since I use k8s ingress and my service is served on path offset.

Is there a way to insert such prefix without modifying production code?

Related documentation fragment:

https://docs.spring.io/spring-restdocs/docs/current/reference/html5/#configuration-uris-webtestclient


Solution

  • To document another URI than the one called to generate documentation, you have to write your own OperationPreprocessor. There are some predefined like Preprocessors.modifyUris but it does not allow to modify the request path.

    Check below the webTestClient configuration and the URIUpdaterOperationRequest class. Code is available on GitHub: https://github.com/Query-Interface/SO-Answers/blob/master/java/spring/rest-docs-modify-uripath/src/test/java/com/example/demo/DemoApplicationTests.java

    public void init() throws Exception {
        final URIUpdaterPreprocessor preprocessor = new URIUpdaterPreprocessor();
        webTestClient = webTestClient.mutate()
            .filter((documentationConfiguration(this.restDocumentation)
                    .operationPreprocessors()
                        .withRequestDefaults(preprocessor)
                        .withResponseDefaults(prettyPrint()))
                    )
            .build();
    }
    
    private static final class URIUpdaterPreprocessor
        implements OperationPreprocessor {
    
        @Override
        public OperationRequest preprocess(OperationRequest request) {
            return new URIUpdaterOperationRequest(request);
        }
    
        @Override
        public OperationResponse preprocess(OperationResponse response) {
            return response;
        }
    
    }
    
    private static final class URIUpdaterOperationRequest
        implements OperationRequest {
    
        private OperationRequest delegate;
    
        public URIUpdaterOperationRequest(OperationRequest request) {
            delegate = request;
        }
    
        public byte[] getContent() {
            return delegate.getContent();
        }
    
        public String getContentAsString() {
            return delegate.getContentAsString();
        }
    
        public HttpHeaders getHeaders() {
            return delegate.getHeaders();
        }
    
        public HttpMethod getMethod() {
            return delegate.getMethod();
        }
    
        public Parameters getParameters() {
            return delegate.getParameters();
        }
    
        public Collection<OperationRequestPart> getParts() {
            return delegate.getParts();
        }
    
        public URI getUri() {
            URI sourceUri = delegate.getUri();
            UriComponentsBuilder builder = UriComponentsBuilder.fromUri(sourceUri);
            return builder
                .host(sourceUri.getHost())
                .replacePath("/service/foo"+sourceUri.getPath())
                .build().toUri();
        }
    
        public Collection<RequestCookie> getCookies() {
            return delegate.getCookies();
        }
    }
    

    I think another possibilty is to update the mustache templates so as to add a prefix before all request path references. The default templates are located here on github.