Skip to content

Commit

Permalink
Added more documentation for REST interfaces.
Browse files Browse the repository at this point in the history
  • Loading branch information
volsch committed Nov 12, 2018
1 parent ce329c2 commit dfcf16a
Show file tree
Hide file tree
Showing 13 changed files with 351 additions and 35 deletions.
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
# to native line endings on checkout.
LICENSE text
*.MF text
*.adoc text
*.csv text
*.html text
*.java text
Expand All @@ -13,6 +14,7 @@ LICENSE text
*.properties text
*.sql text
*.script text
*.snippet text
*.txt text
*.xml text
*.xsd text
Expand Down
48 changes: 48 additions & 0 deletions fhir/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,54 @@
<locations>${db.flyway.locations}</locations>
</configuration>
</plugin>
<plugin>
<groupId>org.asciidoctor</groupId>
<artifactId>asciidoctor-maven-plugin</artifactId>
<executions>
<execution>
<id>generate-docs</id>
<phase>prepare-package</phase>
<goals>
<goal>process-asciidoc</goal>
</goals>
<configuration>
<backend>html</backend>
<doctype>book</doctype>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.springframework.restdocs</groupId>
<artifactId>spring-restdocs-asciidoctor</artifactId>
<version>${spring-restdocs.version}</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution>
<id>copy-resources</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>
${project.build.outputDirectory}/static/docs
</outputDirectory>
<resources>
<resource>
<directory>
${project.build.directory}/generated-docs
</directory>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
67 changes: 67 additions & 0 deletions fhir/src/asciidoc/api-guide.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
= RESTful Notes API Guide
Andy Wilkinson;
:doctype: book
:icons: font
:source-highlighter: highlightjs
:toc: left
:toclevels: 4
:sectlinks:
:operation-curl-request-title: Example request
:operation-http-response-title: Example response

[[overview]]
= Overview

[[overview-http-verbs]]
== HTTP verbs

RESTful notes tries to adhere as closely as possible to standard HTTP and REST conventions in its
use of HTTP verbs.

|===
| Verb | Usage

| `GET`
| Used to retrieve a resource

| `POST`
| Used to create a new resource

| `PATCH`
| Used to update an existing resource, including partial updates

| `DELETE`
| Used to delete an existing resource
|===

[[overview-http-status-codes]]
== HTTP status codes

RESTful notes tries to adhere as closely as possible to standard HTTP and REST conventions in its
use of HTTP status codes.

|===
| Status code | Usage

| `200 OK`
| The request completed successfully

| `201 Created`
| A new resource has been created successfully. The resource's URI is available from the response's
`Location` header

| `204 No Content`
| An update to an existing resource has been applied successfully

| `400 Bad Request`
| The request was malformed. The response body will include an error providing further information

| `404 Not Found`
| The requested resource did not exist
|===

[[overview-headers]]
== Headers

Every response has the following header(s):

Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@
import javax.persistence.OneToMany;
import javax.persistence.OrderBy;
import javax.persistence.Table;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.io.Serializable;
import java.util.List;
import java.util.Objects;
Expand All @@ -64,11 +67,22 @@ public class Code extends VersionedBaseMetadata implements Serializable

public static final int MAX_MAPPED_CODE_LENGTH = 50;

@NotBlank
@Size( max = MAX_NAME_LENGTH )
private String name;

@NotBlank
@Size( max = MAX_CODE_LENGTH )
private String code;

@Size( max = MAX_MAPPED_CODE_LENGTH )
private String mappedCode;

private String description;

@NotNull
private CodeCategory codeCategory;

private List<SystemCode> systemCodes;

@Basic
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
import java.io.Serializable;

/**
Expand All @@ -49,8 +51,14 @@ public class CodeCategory extends VersionedBaseMetadata implements Serializable

public static final int MAX_CODE_LENGTH = 50;

@NotBlank
@Size( max = MAX_NAME_LENGTH )
private String name;

@NotBlank
@Size( max = MAX_CODE_LENGTH )
private String code;

private String description;

@Basic
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package org.dhis2.fhir.adapter.fhir;

/*
* Copyright (c) 2004-2018, University of Oslo
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* Neither the name of the HISP project nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

import org.junit.Before;
import org.junit.Rule;
import org.springframework.restdocs.JUnitRestDocumentation;
import org.springframework.restdocs.mockmvc.RestDocumentationResultHandler;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.transaction.annotation.Transactional;

import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration;
import static org.springframework.restdocs.operation.preprocess.Preprocessors.*;

/**
* Abstract test class that generate REST documentation for JPA repositories.
*
* @author volsch
*/
@Transactional
@Rollback
public abstract class AbstractJpaRepositoryRestDocsTest extends AbstractJpaRepositoryTest
{
@Rule
public final JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation();

protected RestDocumentationResultHandler documentationHandler;

protected MockMvc docMockMvc;

@Before
public void beforeAbstractJpaRepositoryRestDocsTest()
{
documentationHandler = document( "{method-name}",
preprocessRequest( prettyPrint() ),
preprocessResponse( removeHeaders( "X-Content-Type-Options", "X-XSS-Protection", "X-Frame-Options" ), prettyPrint() ) );

docMockMvc = MockMvcBuilders.webAppContextSetup( context )
.apply( documentationConfiguration( restDocumentation ).uris().withPort( 8081 ) )
.alwaysDo( documentationHandler )
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import org.dhis2.fhir.adapter.fhir.data.DataBasePackage;
import org.dhis2.fhir.adapter.fhir.metadata.MetadataBasePackage;
import org.dhis2.fhir.adapter.jackson.JacksonConfig;
import org.junit.Before;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
Expand All @@ -39,18 +40,15 @@
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.rest.webmvc.config.RepositoryRestMvcConfiguration;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.RequestPostProcessor;

import javax.annotation.Nonnull;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;

/**
* Abstract base class for JPA Repository dependent tests.
Expand All @@ -64,20 +62,17 @@
@EntityScan( basePackageClasses = { DataBasePackage.class, MetadataBasePackage.class } )
@SpringBootTest( webEnvironment = SpringBootTest.WebEnvironment.MOCK )
@TestPropertySource( "classpath:test.properties" )
@AutoConfigureMockMvc
@AutoConfigureRestDocs( outputDir = "target/snippets/{class-name}/{method-name}" )
@DataJpaTest
public abstract class AbstractJpaRepositoryTest
{
@Autowired
protected WebApplicationContext context;

protected MockMvc mockMvc;

@Nonnull
protected RequestPostProcessor createRequestPostProcessor()
@Before
public void beforeAbstractJpaRepositoryTest()
{
return request -> {
request.setRemotePort( 8081 );
return request;
};
mockMvc = MockMvcBuilders.webAppContextSetup( context ).build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package org.dhis2.fhir.adapter.fhir;

/*
* Copyright (c) 2004-2018, University of Oslo
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* Neither the name of the HISP project nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

import org.springframework.restdocs.constraints.ConstraintDescriptions;
import org.springframework.restdocs.payload.FieldDescriptor;
import org.springframework.util.StringUtils;

import javax.annotation.Nonnull;

import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath;
import static org.springframework.restdocs.snippet.Attributes.key;

/**
* Contains constrained fields of a class for REST documentation.
*
* @author volsch
*/
public class ConstrainedFields
{
private final ConstraintDescriptions constraintDescriptions;

public ConstrainedFields( @Nonnull Class<?> input )
{
this.constraintDescriptions = new ConstraintDescriptions( input );
}

public FieldDescriptor withPath( @Nonnull String path )
{
return fieldWithPath( path ).attributes( key( "constraints" ).value( StringUtils.collectionToDelimitedString( constraintDescriptions.descriptionsForProperty( path ), ". " ) ) );
}
}
Loading

0 comments on commit dfcf16a

Please sign in to comment.