Now my question is, Why do I even need to use a behaviour? If I were to do this for the second link ^^ it will still work.
defmodule Phoenix.Transports.V2.WebSocketSerializer do
@moduledoc false
# @behaviour Phoenix.Transports.Serializer
alias Phoenix.Socket.{Reply, Message, Broadcast}
@doc """
Translates a `Phoenix.Socket.Broadcast` into a `Phoenix.Socket.Message`.
"""
def fastlane!(%Broadcast{} = msg) do
data = Poison.encode_to_iodata!([nil, nil, msg.topic, msg.event, msg.payload])
{:socket_push, :text, data}
end
.
.
.
So whatâs the point of using behaviour? The Phoenix.Transports.Serializer just defines functions without function body and leaves it to other module to implemente that functionâs body.
You can think of it like a contract that is visibile to the compiler.
Right now the behaviour defines a single function fastlane!/1. What if, in the future, that behaviour changed and added a new function. You would now have fastlane!/1 and foo/2. The compiler will let you know that you have a module that does not fully comply with the contract that has been written.
The @behaviour redirects the dependencies allowing for swappable implementations of the interface. This means the Phoenix framework application code can depend on the Serializer behaviour/interface/contract instead of the WebSocketSerializer directly. So if there were a situation where you need a special serializer, you wouldnât need to fork Phoenix or wait for them to change it. We would just need to implement another Serializer and configure Phoenix to use it.