Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
    Andy Wilkinson
    @wilkinsona
    I'm not a great person to ask about that as I'm not a fan of OpenAPI
    I know there are some tools for testing things to see if they're in sync. https://github.com/RobWin/assertj-swagger is one that comes to mind.
    Eric Deandrea
    @edeandrea
    yeah we actually use that. I’m trying to figure out the best way to tie the human-readable docs back to the actual API contract
    and which should be the “true” source of record
    Mathias Düsterhöft
    @mduesterhoeft
    Also there is this tool to test if a spec is in sync with the implementation - https://bitbucket.org/atlassian/swagger-request-validator
    If you like the test-driven approach of spring-restdocs, and still would like to have an OpenAPI spec you could also look at https://github.com/ePages-de/restdocs-api-spec
    Mathias Düsterhöft
    @mduesterhoeft
    @edeandrea I really like the test-driven approach of spring-restdocs - and I think it is superior over the usual introspection-driven approach that swagger takes. Using the tests to actually derive knowledge about your API is a very good idea. But the design first approach can also be a good fit. It is a good choice if you put an emphasis on your REST API and you want to make it public. Also if you want your development workflow to start with modelling the API. Here you design your API first and use specs like OpenAPI or RAML for this. Then you also need some guarantees to make sure your code is actually implementing this spec.
    Eric Deandrea
    @edeandrea
    Thanks @mduesterhoeft I totally agree. What I’m trying to figure out is what is the best way to only have to write it once :) I’d hate to write it as an OpenAPI/RAML spec and then have to do it again in my RestDocs spec, and then try and keep them in sync. Trying to pick people’s brains about what they are doing in the space so that we truly only have to write things once.
    Mathias Düsterhöft
    @mduesterhoeft
    @edeandrea no of course you would not write your specification twice. What I wanted to say is that there are different approaches:
    • design first - write your API spec up front - maybe using tools such as stoplight.io - that you implement the API. To make sure the implementation follows your specification you can use tools such as swagger-request-validator
    • test-driven - you describe and introspect your API in your test using spring-restdocs - you can use the extension restdocs-api-spec to also generate an openAPI specification for your API - so you rather generate the specification from the knowledge you put into your testt
    Jakub Kubryński
    @jkubrynski
    Hi! Is there any particular reason that HalLinkExtractor does not support links on embedded resources?
    Andy Wilkinson
    @wilkinsona
    IIRC, my reasoning was that the links should be documented for the resource in its main usage so having to document them again in an embedded usage would be unnecessary
    Jakub Kubryński
    @jkubrynski
    But if you document fields of embedded documents it'd be probably also good to not skip the links?
    Andy Wilkinson
    @wilkinsona
    I wouldn't document the fields either. You'll end up with lots of repetition.
    Jakub Kubryński
    @jkubrynski
    OK. I'll review if just linking to other parts of the documentation will be nice
    Jakub Kubryński
    @jkubrynski
    Is it possible to set the default value for the attribute? I want to use custom attribute that will be available only on few fields
    Andy Wilkinson
    @wilkinsona
    @jkubrynski There are a few options discussed in spring-projects/spring-restdocs#291
    Knut Schleßelmann
    @kschlesselmann
    Did anyone here ever setup RestDocs using kotlin and WebTestClient using JUnit5? I cannot get a running setup here :-(
    Andy Wilkinson
    @wilkinsona
    What's the problem?
    Knut Schleßelmann
    @kschlesselmann
    @wilkinsona org.junit.jupiter.api.extension.ParameterResolutionException: Failed to resolve parameter [org.springframework.web.context.WebApplicationContext webApplicationContext] using
    @ExtendWith(RestDocumentationExtension::class, SpringExtension::class)
    internal class DocTest {
    
        private var webTestClient: WebTestClient = WebTestClient.bindToServer().build()
    
        @BeforeEach
        fun setUp(webApplicationContext: WebApplicationContext , restDocumentation: RestDocumentationContextProvider) {
            this.webTestClient = WebTestClient.bindToApplicationContext(webApplicationContext)
                    .configureClient()
                    .filter(documentationConfiguration(restDocumentation))
                    .build()
        }
    
        @Test
        fun stuff() {
            this.webTestClient.get().uri("/").accept(MediaType.APPLICATION_JSON)
                    .exchange().expectStatus().isOk
                    .expectBody().consumeWith(document("index"))
        }
    }
    Would be even better to have some constructor injection setup so that webTestClient could be val
    ```
    @SpringBootTest
    @ActiveProfiles("test")
    @ExtendWith(RestDocumentationExtension::class, SpringExtension::class)
    internal class DocTest {
    doesn't help either
    Or even better: Have @AutoconfigureRestDocs working in webflux
    Andy Wilkinson
    @wilkinsona
    The injection of the WebApplicationContext doesn't have anything to do with REST Docs as it's not involved with that
    I assume that Spring Framework's JUnit 5 integration allows the application context to be injected like that, but I don't know for sure. You'll need some configuration that creates such an application context and I can't see any sign of that in your first example.
    Knut Schleßelmann
    @kschlesselmann
    @wilkinsona Shouldn't the seconad example have a context through @SpringBootTest?
    Knut Schleßelmann
    @kschlesselmann
    @wilkinsona I changed my definition to applicationContext: ApplicationContext and it works :-S
    Knut Schleßelmann
    @kschlesselmann
    Anyone an idea why my base url is still localhost:8080 if I use the following to bootstrap my RestDocs tests
    @SpringBootTest
    @ActiveProfiles("test")
    @ExtendWith(RestDocumentationExtension::class, SpringExtension::class)
    internal abstract class AbstractRestDocsTest {
    
        protected var webTestClient: WebTestClient = WebTestClient.bindToServer().build()
    
        @BeforeEach
        fun setUp(applicationContext: ApplicationContext, restDocumentation: RestDocumentationContextProvider) {
            webTestClient = WebTestClient.bindToApplicationContext(applicationContext)
                    .configureClient()
                    .baseUrl("https://${applicationContext.applicationName}.example.com")
                    .filter(documentationConfiguration(restDocumentation)
                            .operationPreprocessors()
                            .withRequestDefaults(prettyPrint())
                            .withResponseDefaults(prettyPrint()))
                    .build()
        }
    }
    Andy Wilkinson
    @wilkinsona
    Why are you creating it twice, once bound to a server and once bound to the application context?
    Knut Schleßelmann
    @kschlesselmann
    @wilkinsona So I can use var without null. Some kind of constructor injection would be nice … or @AutoConfigureRestDocs for WebTestClient :-)
    But does it matter since I override the instance later on?
    Andy Wilkinson
    @wilkinsona
    @AutoConfigureRestDocs already works with WebTestClient
    The duplicate configuration of WebTestClient matters in this context as it makes it harder to figure out what you're doing and why.
    Andy Wilkinson
    @wilkinsona
    Looks like we missed a doc update as part of https://github.com/spring-projects/spring-boot/pull/10969/. It's been supported since 2.0
    Knut Schleßelmann
    @kschlesselmann
    Good to know … never tried since it was missing in the docs :-)
    @wilkinsona So how would for example pretty print work with WebTestClient If I use @AutoConfigureRestDocs?
    Andy Wilkinson
    @wilkinsona
    You'd set it up with a RestDocsWebTestClientConfigurationCustomizer
    Knut Schleßelmann
    @kschlesselmann
    OK, let me try :-) @wilkinsona awesome work btw :thumbsup:
    Knut Schleßelmann
    @kschlesselmann

    @wilkinsona Works like a charm :-) The base url is still a problem though. I tried

    @TestConfiguration
    internal class RestDocsConfiguration : RestDocsWebTestClientConfigurationCustomizer {
    
        override fun customize(configurer: WebTestClientRestDocumentationConfigurer) {
            configurer.operationPreprocessors()
                    .withRequestDefaults(prettyPrint())
                    .withResponseDefaults(prettyPrint())
        }
    
        @Bean
        fun webTestClientBuilderCustomizer() = WebTestClientBuilderCustomizer {
            it
                    .baseUrl("https://fooo.bar")
        }
    }

    Pretty print is applied as expected … my snippets still refer to localhost:8080. Would those cusomizers be picked up by

    @SpringBootTest
    @ActiveProfiles("test")
    @AutoConfigureRestDocs
    @AutoConfigureWebTestClient
    @Import(RestDocsConfiguration::class)
    @ExtendWith(RestDocumentationExtension::class, SpringExtension::class)
    internal abstract class AbstractRestDocsTest {
    
        @Autowired
        protected lateinit var webTestClient: WebTestClient
    }

    at all?

    Andy Wilkinson
    @wilkinsona
    A WebTestClientBuilderCustomizer not being picked up sounds very similar to spring-projects/spring-boot#15132
    Knut Schleßelmann
    @kschlesselmann
    Yeah … let's see how this turns out
    Thanks again
    Knut Schleßelmann
    @kschlesselmann
    Can you somehow propagate the .optional() information to the generated snippets? For example ${parameterName} (optional) in the first column of the table?
    Andy Wilkinson
    @wilkinsona
    Yes. The value of optional is already included in the model. If you want it to appear in the generated snippets, you can provide a custom template and use {{optional}}
    Christopher Kocel
    @kkocel
    Hello, I have a question - is there a possibility to add path to base url that will mask (localhost:8080) ?
    wykaPedia
    @wykapedia
    @kkocel yes, you can use the URI configurer to achieve this: