How does BEAM work? What does cowboy do exactly? and what exactly is Plug?
I still don’t have a clarity between these things. Can someone explain it please?
How does BEAM work? What does cowboy do exactly? and what exactly is Plug?
I still don’t have a clarity between these things. Can someone explain it please?
BEAM is the acronym of Bogdan/Björn’s Erlang Virtual Machine and is one of the implementation of Erlang VM (others are JAM, Lumen, Enigma, ErlangRT, AtomVM). This one is most popular one, and is the Erlang VM (reference implementation). Think of it as an OpenJVM vs Dalvik/OracleJVM/etc. in Java world.
Cowboy is HTTP(S) and WebSocket server, think of it like Glassfish/Jetty/Tomcat in Java world, or WEBrick/Puma/Unicorn in Ruby world.
Plug is common interface for HTTP servers. This is more like Rack in Ruby universe.
So in short:
can you please explain how these three things work together? like what runs where?
Thanks, that gave me a better idea
As per Plug documentation
Plug is:
- A specification for composable modules between web applications
- Connection adapters for different web servers in the Erlang VM
What does this mean?
A plug is just a function that accepts a Plug.Conn.t
and a configuration “thing” (I just want to say “object” but Elixir is not object oriented so I don’t know how to name it. A “term”?) That function can be wrapped in a separate module (something like a functor if you are familiar with C++).
If a function accepts the same arguments as above, changes the conn a little bit, and delegates the job to a plug, then the function is another plug.
In this way, you can chain plugs together, with each plug handles only a small task in the whole HTTP request handling, and the result of the chaining is a big plug. That’s what “composable” means. For example, in a conventional Phoenix application, you can find Plug.RequestId
which attaches a unique random string to each request for the DevOps team to trace every request; Plug.Parsers
for parsing the query strings and request bodies; Plug.MethodOverride
for overriding the method according to the _method
param; Plug.Session
for loading sessions, and finally the MyApp.Router
for dispatching each request to the correct controller action. (I omitted a few plugs) These plugs combine together into a single big plug.
If an Erlang/Elixir web server can chew and spit Plug.Conn.t
, it can run any plug-based web application such as Phoenix application. If it can’t, well, probably someone will write or has already written an adapter for that server. So you can think of Plug as an adapter between your web application and the plug-aware web server, and that’s what “Connection adapters” mean.
@shijith.k I’ve actually wrote a small deep-dive into Plug and Cowboy and how they work under the hood which you can read here hope it helps!