elixirphoenix-frameworkmsgpack

Use custom serializer like MessagePack with Phoenix Framework


Phoenix 1.3
Elixir 1.5.2 compiled with Erlang 20

I have an Android mobile app which sends and receives MsgPack with a HTTP server. Now we are planning to integrate Phoenix framework for some parts. But sending binaries specifically MsgPack is troublesome on Phoenix framework.

How to use custom (de-)serializers like MsgPack in Phoenix?

If it is of any relevance: 1. Using MsgPax library
2. Checked this link on stoiximan.gr


Solution

  • I've used MsgPax to do this, and it works just fine. First add it to your mix.exs file.

    To use a custom serializer:

    Then, as according to the docs, your serializer has to have 3 functions: decode!/2, encode!/1, and fastlane!/1. So, copying mostly from phoenix's own implementation, your serializer might look something like this:

    defmodule YourApp.MsgpaxSerializer do
      @behaviour Phoenix.Transports.Serializer
    
      alias Phoenix.Socket.Reply
      alias Phoenix.Socket.Message
      alias Phoenix.Socket.Broadcast
    
      def fastlane!(%Broadcast{} = msg) do
        msg = %Message{topic: msg.topic, event: msg.event, payload: msg.payload}
    
        {:socket_push, :binary, encode_to_binary(msg)}
      end
    
      def encode!(%Reply{} = reply) do
        msg = %Message{
          topic: reply.topic,
          event: "phx_reply",
          ref: reply.ref,
          payload: %{status: reply.status, response: reply.payload}
        }
        {:socket_push, :binary, encode_to_binary(msg)}
      end
      def encode!(%Message{} = msg) do
        {:socket_push, :binary, encode_to_binary(msg)}
      end
    
      defp encode_to_binary(msg) do
        msg |> Map.from_struct() |> Msgpax.pack!()
      end
    
      def decode!(message, _opts) do
        message
        |> Msgpax.unpack!()
        |> Phoenix.Socket.Message.from_map!()
      end
    end
    

    Finally, if you are encoding structs, you may have to add @derive Msgpax.Packer attribute to the modules containing the structs as detailed in Msgpax's documentation.