マルチパート

Spring REST Docs provides support for documenting multipart requests.

リクエストパート

requestParts を使用して、マルチパートリクエストのパーツをドキュメント化できます。次の例は、その方法を示しています。

  • MockMvc

  • WebTestClient

import org.junit.jupiter.api.Test;

import org.springframework.test.web.servlet.MockMvc;

import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.request.RequestDocumentation.partWithName;
import static org.springframework.restdocs.request.RequestDocumentation.requestParts;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.multipart;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

class RequestParts {

	// Fields

	private MockMvc mockMvc;


	@Test
	void test() throws Exception {
		this.mockMvc.perform(multipart("/upload").file("file", "example".getBytes())) (1)
			.andExpect(status().isOk())
			.andDo(document("upload", requestParts((2)
					partWithName("file").description("The file to upload")) (3)
			));
	}

}
1file という名前の単一のパーツで POST リクエストを実行します。
2 リクエストの部分を説明するスニペットを生成するように Spring REST Docs を構成します。org.springframework.restdocs.request.RequestDocumentation で静的 requestParts メソッドを使用します。
3file という名前のパーツをドキュメント化します。org.springframework.restdocs.request.RequestDocumentation で静的 partWithName メソッドを使用します。
import org.junit.jupiter.api.Test;

import org.springframework.test.web.reactive.server.WebTestClient;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.reactive.function.BodyInserters;

import static org.springframework.restdocs.request.RequestDocumentation.partWithName;
import static org.springframework.restdocs.request.RequestDocumentation.requestParts;
import static org.springframework.restdocs.webtestclient.WebTestClientRestDocumentation.document;

class RequestParts {

	// Fields


	private WebTestClient webTestClient;


	@Test
	void test() {
		MultiValueMap<String, Object> multipartData = new LinkedMultiValueMap<>();
		multipartData.add("file", "example".getBytes());
		this.webTestClient.post()
			.uri("/upload")
			.body(BodyInserters.fromMultipartData(multipartData)) (1)
			.exchange()
			.expectStatus()
			.isOk()
			.expectBody()
			.consumeWith(document("upload", requestParts((2)
					partWithName("file").description("The file to upload")) (3)
			));
	}

}
1file という名前の単一のパーツで POST リクエストを実行します。
2 リクエストの部分を説明するスニペットを生成するように Spring REST Docs を構成します。org.springframework.restdocs.request.RequestDocumentation で静的 requestParts メソッドを使用します。
3file という名前のパーツをドキュメント化します。org.springframework.restdocs.request.RequestDocumentation で静的 partWithName メソッドを使用します。

結果は、リソースでサポートされているリクエストパーツを説明するテーブルを含む request-parts.adoc という名前のスニペットです。

リクエストパーツをドキュメント化する場合、ドキュメント化されていないパーツがリクエストで使用されていると、テストは失敗します。同様に、ドキュメント化された部分がリクエスト内に見つからず、その部分がオプションとしてマークされていない場合も、テストは失敗します。

ドキュメント化されていない部分がテストの失敗を引き起こさないリラックスしたモードでリクエスト部分をドキュメント化することもできます。これを行うには、org.springframework.restdocs.request.RequestDocumentation で relaxedRequestParts メソッドを使用します。これは、リクエストパーツのサブセットのみに注目したい特定のシナリオをドキュメント化する場合に役立ちます。

リクエストパーツをドキュメント化したくない場合は、無視するようにマークできます。これにより、前述の失敗を回避しながら、生成されたスニペットに表示されなくなります。

ペイロードのリクエストパート

リクエストパーツのペイロードは、リクエストパーツの本文とそのフィールドのドキュメント化をサポートすることで、リクエストのペイロードとほぼ同じ方法でドキュメント化できます。

リクエストパーツの本文のドキュメント化

次のように、リクエストパーツの本文を含むスニペットを生成できます。

  • MockMvc

  • WebTestClient

import org.junit.jupiter.api.Test;

import org.springframework.http.MediaType;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.test.web.servlet.MockMvc;

import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.multipart;
import static org.springframework.restdocs.payload.PayloadDocumentation.requestPartBody;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

class RequestPartBody {

	// Fields

	private MockMvc mockMvc;


	@Test
	void test() throws Exception {
		MockMultipartFile image = new MockMultipartFile("image", "image.png", "image/png", "<<png data>>".getBytes());
		MockMultipartFile metadata = new MockMultipartFile("metadata", "", "application/json",
				"{ \"version\": \"1.0\"}".getBytes());

		this.mockMvc.perform(multipart("/images").file(image).file(metadata).accept(MediaType.APPLICATION_JSON))
			.andExpect(status().isOk())
			.andDo(document("image-upload", requestPartBody("metadata"))); (1)
	}

}
1Spring REST ドキュメントを構成して、metadata という名前のリクエストパーツの本文を含むスニペットを生成します。PayloadDocumentation で静的 requestPartBody メソッドを使用します。
import java.util.Collections;

import org.junit.jupiter.api.Test;

import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.Resource;
import org.springframework.http.MediaType;
import org.springframework.test.web.reactive.server.WebTestClient;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.reactive.function.BodyInserters;

import static org.springframework.restdocs.payload.PayloadDocumentation.requestPartBody;
import static org.springframework.restdocs.webtestclient.WebTestClientRestDocumentation.document;

class RequestPartBody {

	// Fields

	private WebTestClient webTestClient;


	@Test
	void test() {
		MultiValueMap<String, Object> multipartData = new LinkedMultiValueMap<>();
		Resource imageResource = new ByteArrayResource("<<png data>>".getBytes()) {

			@Override
			public String getFilename() {
				return "image.png";
			}

		};
		multipartData.add("image", imageResource);
		multipartData.add("metadata", Collections.singletonMap("version", "1.0"));

		this.webTestClient.post()
			.uri("/images")
			.body(BodyInserters.fromMultipartData(multipartData))
			.accept(MediaType.APPLICATION_JSON)
			.exchange()
			.expectStatus()
			.isOk()
			.expectBody()
			.consumeWith(document("image-upload", requestPartBody("metadata"))); (1)
	}

}
1Spring REST ドキュメントを構成して、metadata という名前のリクエストパーツの本文を含むスニペットを生成します。PayloadDocumentation で静的 requestPartBody メソッドを使用します。

その結果、パーツの本体を含む request-part-${part-name}-body.adoc という名前のスニペットが作成されます。例: metadata という名前のパーツをドキュメント化すると、request-part-metadata-body.adoc という名前のスニペットが生成されます。

リクエストパーツのフィールドのドキュメント化

次のように、リクエストまたはレスポンスのフィールドとほぼ同じ方法で、リクエストパーツのフィールドをドキュメント化できます。

  • MockMvc

  • WebTestClient

import org.junit.jupiter.api.Test;

import org.springframework.http.MediaType;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.test.web.servlet.MockMvc;

import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.multipart;
import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath;
import static org.springframework.restdocs.payload.PayloadDocumentation.requestPartFields;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

class RequestPartFields {

	// Fields

	private MockMvc mockMvc;


	@Test
	void test() throws Exception {
		MockMultipartFile image = new MockMultipartFile("image", "image.png", "image/png", "<<png data>>".getBytes());
		MockMultipartFile metadata = new MockMultipartFile("metadata", "", "application/json",
				"{ \"version\": \"1.0\"}".getBytes());

		this.mockMvc.perform(multipart("/images").file(image).file(metadata).accept(MediaType.APPLICATION_JSON))
			.andExpect(status().isOk())
			.andDo(document("image-upload", requestPartFields("metadata", (1)
					fieldWithPath("version").description("The version of the image")))); (2)
	}

}
1Spring REST ドキュメントを構成して、metadata という名前のリクエストパーツのペイロード内のフィールドを説明するスニペットを生成します。PayloadDocumentation で静的 requestPartFields メソッドを使用します。
2 パスが version のフィールドが必要です。org.springframework.restdocs.payload.PayloadDocumentation で静的 fieldWithPath メソッドを使用します。
import java.util.Collections;

import org.junit.jupiter.api.Test;

import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.Resource;
import org.springframework.http.MediaType;
import org.springframework.test.web.reactive.server.WebTestClient;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.reactive.function.BodyInserters;

import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath;
import static org.springframework.restdocs.payload.PayloadDocumentation.requestPartFields;
import static org.springframework.restdocs.webtestclient.WebTestClientRestDocumentation.document;

class RequestPartFields {

	// Fields

	private WebTestClient webTestClient;


	@Test
	void test() {
		MultiValueMap<String, Object> multipartData = new LinkedMultiValueMap<>();
		Resource imageResource = new ByteArrayResource("<<png data>>".getBytes()) {

			@Override
			public String getFilename() {
				return "image.png";
			}

		};
		multipartData.add("image", imageResource);
		multipartData.add("metadata", Collections.singletonMap("version", "1.0"));
		this.webTestClient.post()
			.uri("/images")
			.body(BodyInserters.fromMultipartData(multipartData))
			.accept(MediaType.APPLICATION_JSON)
			.exchange()
			.expectStatus()
			.isOk()
			.expectBody()
			.consumeWith(document("image-upload", requestPartFields("metadata", (1)
					fieldWithPath("version").description("The version of the image")))); (2)
	}

}
1Spring REST ドキュメントを構成して、metadata という名前のリクエストパーツのペイロード内のフィールドを説明するスニペットを生成します。PayloadDocumentation で静的 requestPartFields メソッドを使用します。
2 パスが version のフィールドが必要です。org.springframework.restdocs.payload.PayloadDocumentation で静的 fieldWithPath メソッドを使用します。

結果は、パーツのフィールドを説明するテーブルを含むスニペットです。このスニペットの名前は request-part-${part-name}-fields.adoc です。例: metadata という名前のパーツをドキュメント化すると、request-part-metadata-fields.adoc という名前のスニペットが生成されます。

フィールドをドキュメント化する場合、パーツのペイロードにドキュメント化されていないフィールドが見つかった場合、テストは失敗します。同様に、ドキュメント化されたフィールドがパーツのペイロードに見つからず、そのフィールドがオプションとしてマークされていない場合も、テストは失敗します。階層構造を持つペイロードの場合、フィールドをドキュメント化するだけで、そのすべての子孫もドキュメント化されたものとして扱われます。

フィールドをドキュメント化したくない場合は、無視するようにマークできます。そうすることで、上記の失敗を回避しながら、生成されたスニペットに表示されなくなります。

ドキュメント化されていないフィールドがテストの失敗の原因にならない、緩和モードでフィールドをドキュメント化することもできます。これを行うには、org.springframework.restdocs.payload.PayloadDocumentation で relaxedRequestPartFields メソッドを使用します。これは、パーツのペイロードのサブセットのみに注目したい特定のシナリオをドキュメント化する場合に役立ちます。

フィールドの説明、XML を使用するペイロードのドキュメント化などの詳細については、リクエストおよびレスポンスペイロードのドキュメント化に関するセクションを参照してください。