I need to document an API that accepts a JSON represented by this class:
public class Message {
@NotNull(message = "Sender cannot be null")
private String sender;
@Pattern(regexp="HI|HELLO",message = "Message can be only 'HI' or 'HELLO'")
private String content;
// Constructor, Getters and Setters..
}
Spring Docs autogenerates the following snippet:
.Request fields:
|===
|Path|Type|Constraints|Description
|sender
|String
|Must not be null
|Sender of the message
|content
|String
|Must match the regular expression `HI|HELLO`
|Content of the message
|===
Which is used by Asciidoctor to create a table in the pdf. However, in the pdf, the table is broken (because of the pipe):
How can I escape the pipe within the regular expression?
I found this issue, but seems to be related to another project.
This is the test class to generate the documentation (JUnit5):
@WebMvcTest(HomeController.class)
@AutoConfigureRestDocs(outputDir = "target/snippets")
public class HomeControllerTest {
@Autowired
private MockMvc mockMvc;
@Test
public void postMessageTest() throws Exception {
ConstrainedFields constrainedFields = new ConstrainedFields(Message.class);
this.mockMvc
.perform(post("/message").content("{\"sender\":\"Marc\",\"content\":\"HI\"}")
.characterEncoding("utf-8")
.contentType(MediaType.APPLICATION_JSON))
.andDo(print()).andExpect(status().isOk())
.andDo(document("home-message", requestFields(
attributes(key("title").value("Request fields:")),
constrainedFields.withPath("sender").description("Sender of the message"),
constrainedFields.withPath("content").description("Content of the message")
)));
}
private static class ConstrainedFields {
private final ConstraintDescriptions constraintDescriptions;
ConstrainedFields(Class<?> input) {
this.constraintDescriptions = new ConstraintDescriptions(input);
}
private FieldDescriptor withPath(String property) {
return fieldWithPath(property).attributes(key("constraints").value(
// Let's assume there is only one constraint for each property
constraintDescriptions.descriptionsForProperty(property).get(0)));
}
}
}
The full project to reproduce the issue is here.
probably not the best solution, but, after doing little research, I found out that a simple
\
character is enough to escape pipe character inasciidoctor
documents (source). our goal then is to get this line in the.adoc
snippet:this is the method that extracts "constraints descriptions" in your code:
here we have "full control" over the text that will be written in the
.adoc
. we could for example take the constraint description fromconstraintDescriptions.descriptionsForProperty(property)
, apply our escaping and than pass the escaped string to.value()
:this will produce the escaped line in the
.adoc
and will be correctly rendered in the.pdf
: