2017年5月30日火曜日

go-swagger で XML なレスポンスを返却する方法

概要

デフォルトだと application/json としてレスポンスが返却されます
レスポンスを XML として返却できないか試してみたので紹介します

環境

  • CentOS 7.3.1611
  • golang 1.8
  • swagger 2.0
  • go-swagger 0.10.0

swagger.yml

  • vim swagger.yml
consumes:
- application/json
info:
  description: The product of a tutorial on goswagger.io
  title: A To Do list application
  version: 1.0.0
produces:
- application/xml
schemes:
- http
swagger: "2.0"
basePath: /v1
definitions:
  item:
    type: object
    required:
      - description
    properties:
      id:
        type: integer
        format: int64
        readOnly: true
      description:
        type: string
        minLength: 1
      completed:
        type: boolean
  error:
    type: object
    required:
      - message
    properties:
      code:
        type: integer
        format: int64
      message:
        type: string
paths:
  /:
    get:
      tags:
        - todos
      operationId: findTodos
      parameters:
        - name: since
          in: query
          type: integer
          format: int64
        - name: limit
          in: query
          type: integer
          format: int32
          default: 20
      responses:
        200:
          description: list the todo operations
          schema:
            type: array
            items:
              $ref: "#/definitions/item"
        default:
          description: generic error response
          schema:
            $ref: "#/definitions/error"

ポイントは produces の部分でここでレスポンス時の Content-Type を application/xml に固定します

produces:
- application/xml

コード生成

  • swagger generate server -f swagger.yml

メイン部分修正

  • vim configure_a_to_do_list_application.go

一部抜粋です
適当に値を返す処理を追加します

api.TodosFindTodosHandler = todos.FindTodosHandlerFunc(func(params todos.FindTodosParams) middleware.Responder {
        result := make([]*models.Item, 0)
        item := new(models.Item)
        item.Completed = true
        s := "hoge"
        item.Description = &s
        result = append(result, item)
        return todos.NewFindTodosOK().WithPayload(result)
})

アプリ起動

  • go install ./cmd/a-to-do-list-application-server/
  • a-to-do-list-application-server --host 0.0.0.0 --port 18080

動作確認

  • curl localhost:18080/v1 | xmllint --format -

とすると

<?xml version="1.0"?>
<Item>
  <Completed>true</Completed>
  <Description>hoge</Description>
  <ID>0</ID>
</Item>

という感じで XML が返ってきます
-v で詳細を見ると Content-Type も application/xml となっているのが確認できると思います

追加調査

とりあえずこれで自分が実装する API の部分に関しては XML で返却することができます
ただ、go-swagger がデフォルトで実装しているエラーハンドリングの部分に関しては json で返ってきてしまいます
例えば今回であれば「/」にアクセスした場合、Not Found のエラーになるのですが、それが

{"code":404,"message":"path / was not found"}

となってしまいます
他には Method Not Allowed なども json になってしまいます

{"code":405,"message":"method POST is not allowed, but [GET] are"}

このあたりのデフォルトエラーに関しても XML にしたいと思います
デフォルトエラーのカスタマイズ方法についてはまだ調査できていないので別途調査が必要かなと思います

最後に

go-swagger で XML のレスポンスを返却する方法を紹介しました
基本は consumes の設定を変更するだけで XML にすることができました

0 件のコメント:

コメントを投稿