[Django]Django REST frameworkでMessagePackを使う


Django REST frameworkでMessagePackを使う

Django REST frameworkアプリケーションの、HTTPリクエスト/レスポンスはデフォルトではJSONを想定しています。
JSONも良いんですが、MessagePack使いたいですよね。

これを変更するにはParsers/Renderersを設定します。

リクエスト - Parsers
レスポンス - Renderers

デフォルトではMessagePackはサポートしていませんが、ドキュメントにdjangorestframework-msgpackを使えと書いてあります。

MessagePack is a fast, efficient binary serialization format.
Juan Riaza maintains the djangorestframework-msgpack package which provides MessagePack renderer and parser support for REST framework.

djangorestframework-msgpack

djangorestframework-msgpackをインストールします。

pip install djangorestframework-msgpack

setting.pyにMessagePackを利用するように設定します。

REST_FRAMEWORK = {
    'DEFAULT_PARSER_CLASSES': (
        'rest_framework_msgpack.parsers.MessagePackParser',
    ),
    'DEFAULT_RENDERER_CLASSES': (
        'rest_framework_msgpack.renderers.MessagePackRenderer',
    ),
}

これでMessagePackを使うようになりました。

あとはおまけです。

Django REST Swaggerも使う

Django REST Swaggerを使っているんですが、MessagePackを利用する方法がわかりません。
※ 知ってたら教えてください。

なので、Swaggerを利用する環境(ここではDEBUG=Trueの場合)はJSONも利用できるようにしています。

if DEBUG == True:
    REST_FRAMEWORK = {
        'DEFAULT_PARSER_CLASSES': (
            'rest_framework_msgpack.parsers.MessagePackParser',
            'rest_framework.parsers.JSONParser',
        ),
        'DEFAULT_RENDERER_CLASSES': (
            'rest_framework_msgpack.renderers.MessagePackRenderer',
            'rest_framework.renderers.JSONRenderer',
            'rest_framework.renderers.BrowsableAPIRenderer',
        ),
    }
else:
    REST_FRAMEWORK = {
        'DEFAULT_PARSER_CLASSES': (
            'rest_framework_msgpack.parsers.MessagePackParser',
        ),
        'DEFAULT_RENDERER_CLASSES': (
            'rest_framework_msgpack.renderers.MessagePackRenderer',
        ),
    }

並び順が大切です。
一番上がメインなのでMessagePackをメインに書きます。

BrowsableAPIRendererはこれ用です。
今は使ってないんですが入れてみました。

通信のテストはMessagePackでやる

通信のテストするときはMessagePackを使うように書きます。
JSONでテストをしても意味ないです。

import msgpack

from django.test import TestCase

class ApiUsersTestCase(TestCase):
    def test_put_users_pk_ok(self):
        """
        例えばユーザーのパラメータを設定するようなAPI
        イメージなので簡単なテストだけ
        """

        pk = 1
        params = {
            "name": "トランプ"
        }

        response = self.client.put("/users/{0}/".format(pk), msgpack.packb(params, use_bin_type=True), "application/msgpack")
        self.assertEqual(response.status_code, 201)

        content = msgpack.unpackb(response.content, encoding='utf-8')
        self.assertEqual(content["name"], params["name"])