Skip to content

Support for passing custom values/services into Snippet classes #308

@jmisur

Description

@jmisur

In our auto-documentation extension https://github.com/ScaCap/spring-auto-restdocs we are trying to automate documentation as much as possible by introspecting code. For this we created extensions of Snippets which are dependent on some common services, such as jackson ObjectMapper, custom constraints & javadoc reader, having HandlerMethod available etc.

For passing these common components around, we are doing little hack by putting custom attributes inside MockHttpServletRequest, then inside the Snippet class getting them from Operation attributes:

    public static ObjectMapper getObjectMapper(Operation operation) {
        return (ObjectMapper) operation.getAttributes().get(ObjectMapper.class.getName());
    }

    public static void setObjectMapper(MockHttpServletRequest request, ObjectMapper objectMapper) {
        ((Map) request.getAttribute(ATTRIBUTE_NAME_CONFIGURATION))
                .put(ObjectMapper.class.getName(), objectMapper);
    }

https://github.com/ScaCap/spring-auto-restdocs/blob/master/spring-auto-restdocs-core/src/main/java/capital/scalable/restdocs/OperationAttributeHelper.java

We are setting it for every request using custom ResultHandler and alwaysDo mechanism.

        public void handle(MvcResult result) throws Exception {
            setHandlerMethod(result.getRequest(), (HandlerMethod) result.getHandler());
            setObjectMapper(result.getRequest(), objectMapper);
            ...

https://github.com/ScaCap/spring-auto-restdocs/blob/master/spring-auto-restdocs-core/src/main/java/capital/scalable/restdocs/jackson/JacksonResultHandlers.java

Because we need custom data for every request, such as request pattern and HandlerMethod, we cannot configure these things statically during Snippet class creation.

As this mechanism is basically a hack to inner workings of spring-restdocs (discovered how these attributes are passed around by digging in source code) and it's prone to change as it's internal api, it would be great if this framework offers customization of such things out of the box. Could be still using these attributes internally but having some convenient public api.

Activity

wilkinsona

wilkinsona commented on Sep 27, 2016

@wilkinsona
Member

I'm not sure about a public API for adding arbitrary attributes. I'm not too keen on the way that things are passed around internally at the moment, so building something that's public on top of that doesn't feel right. Perhaps we can find another way to meet your goal.

What, specifically, do you need to access in your snippet?

wilkinsona

wilkinsona commented on Dec 16, 2016

@wilkinsona
Member

Closing due to the lack of the requested information. @jmisur If you can provide the required information we can take another look at this.

jmisur

jmisur commented on Feb 18, 2017

@jmisur
Author

Hi @wilkinsona, sorry for not responding for such a long time. Our project stalled a bit, but we are back contributing to it.

So for us specifically, we need to access these objects in our Snippet classes:

  • HandlerMethod from which we are able extract information about request/response types, method name, etc
  • Jackson ObjectMapper to analyse request/response types of the endpoint and write out the field names, etc.
  • custom JavadocReader which helps reading comments used on request/response fields and methods
  • org.springframework.web.servlet.HandlerMapping.bestMatchingPattern to output actual endpoint path used when processing the request
  • instance of PropertyPlaceholderHelper used in StandardWriterResolver so that we can construct import links to other snippet files (currently we create it on our own inspired from StandardWriterResolver)
  • custom ConstraintReader which reads JSR-303 constraints from request/response fields and method parameters and produces appropriate messages
  • custom authorization string, which is passed to request configuration via RequestPostProcessor which also sets the Authorization header for the specific user used in that request

So that's about it. Half of the stuff are custom beans, which we need to access inside Snippets and some things are hacked out of existing org.springframework.restdocs.configuration attribute of the Operation.

Any ideas how to access these things without hacking the Operation's attributes are welcome!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @jmisur@wilkinsona@spring-projects-issues

        Issue actions

          Support for passing custom values/services into Snippet classes · Issue #308 · spring-projects/spring-restdocs