前回、SpringMVC 4.1のProtocol Buffers対応を紹介しましたが、今イチ使いどころがわからない感じでした。
ただ、ProtobufHttpMessageConverterのソースコードを読んでいると面白いことがわかりました。Content Negotiation対応しているのです。
つまり、デフォルトではProtobufに対応しますが、JSONをリクエストすればJSON形式で返しますし、XMLをリクエストすればXML形式で返します。
例えば、Protobufで用意したAPIをデバッグするのにはJSONで見た方が分かりやすいでしょうし、WebブラウザにはJSONでやり取りした方が効率が良いでしょう。テストもJSONの方がやりやすいです。
この機能を有効にするにはprotobuf-java-formatを依存ライブラリに追加する必要があります。
<dependency>
<groupId>com.googlecode.protobuf-java-format</groupId>
<artifactId>protobuf-java-format</artifactId>
<version>1.2</version>
</dependency>
前回のサンプルコードで試してみましょう。
Controllerを再掲しておくと
@RestController
public class AddressBookController {
@RequestMapping("person")
AddressBookProtos.Person person() {
return AddressBookProtos.Person.newBuilder()
.setId(1234)
.setName("John Doe")
.setEmail("[email protected]")
.addPhone(
AddressBookProtos.Person.PhoneNumber.newBuilder()
.setNumber("555-4321")
.setType(AddressBookProtos.Person.PhoneType.HOME))
.build();
}
}
こんなんでした。
Protobuf
$ curl -v http://localhost:8080/person
> GET /person HTTP/1.1
> User-Agent: curl/7.30.0
> Host: localhost:8080
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: Apache-Coyote/1.1
< X-Protobuf-Schema: src/main/proto/tutorial/addressbook.proto
< X-Protobuf-Message: tutorial.Person
< Content-Type: application/x-protobuf;charset=UTF-8
< Content-Length: 45
< Date: Sun, 14 Dec 2014 15:39:05 GMT
<
John Doe� [email protected]"
JSON
$ curl -v http://localhost:8080/person.json
> GET /person.json HTTP/1.1
> User-Agent: curl/7.30.0
> Host: localhost:8080
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: Apache-Coyote/1.1
< Content-Type: application/json;charset=UTF-8
< Transfer-Encoding: chunked
< Date: Sun, 14 Dec 2014 15:39:42 GMT
<
{"name": "John Doe","id": 1234,"email": "[email protected]","phone": [{"number": "555-4321","type": "HOME"}]}
or
$ curl -v -H "Accept: application/json" http://localhost:8080/person
> GET /person HTTP/1.1
> User-Agent: curl/7.30.0
> Host: localhost:8080
> Accept: application/json
>
< HTTP/1.1 200 OK
< Server: Apache-Coyote/1.1
< Content-Type: application/json;charset=UTF-8
< Transfer-Encoding: chunked
< Date: Sun, 14 Dec 2014 15:40:35 GMT
<
{"name": "John Doe","id": 1234,"email": "[email protected]","phone": [{"number": "555-4321","type": "HOME"}]}
XML
$ curl -v http://localhost:8080/person.xml
> GET /person.xml HTTP/1.1
> User-Agent: curl/7.30.0
> Host: localhost:8080
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: Apache-Coyote/1.1
< Content-Type: application/xml;charset=UTF-8
< Transfer-Encoding: chunked
< Date: Sun, 14 Dec 2014 15:41:48 GMT
<
<Person><name>John Doe</name><id>1234</id><email>[email protected]</email><phone><number>555-4321</number><type>HOME</type></phone></Person>
or
$ curl -v -H "Accept: application/xml" http://localhost:8080/person
> GET /person HTTP/1.1
> User-Agent: curl/7.30.0
> Host: localhost:8080
> Accept: application/xml
>
< HTTP/1.1 200 OK
< Server: Apache-Coyote/1.1
< Content-Type: application/xml;charset=UTF-8
< Transfer-Encoding: chunked
< Date: Sun, 14 Dec 2014 15:42:26 GMT
<
<Person><name>John Doe</name><id>1234</id><email>[email protected]</email><phone><number>555-4321</number><type>HOME</type></phone></Person>
E2Eテストコードはこんな感じ。
こいつ、かなりやれるぞ・・・!
ProtocolBuffers RPCのサーバーサイド用途にかなり合っているのではないでしょうか。