You can find some hints online about how to use CowBoy from Elixir but they are often I then add CowBoy dependencies to the mix.exs file. Phoenix is a web development framework written in the functional programming language Elixir. Phoenix uses a server-side model-view-controller (MVC) pattern. Based on the Plug library, and ultimately the Cowboy Erlang framework, Print/export. Download as PDF · Printable version. Elixir: Building a Small JSON Endpoint With Plug, Cowboy and Poison This looks like a lot, but most of this file is just some helpful comments. The gist is, we.
Cowboy download file elixi - that
Cowboy download file elixi - remarkable
Create an Elixir web app using Cowboy
This post is a part of my upcoming book on Phoenix 1.3.
By the end of this post you will learn
- What is Cowboy?
- Minimal code to say "Hello World!" on the browser and in that process understand the Cowboy internals.
- Understand what flexibility Plug/Phoenix provides and why you need it instead of using just Cowboy.
What is Cowboy?
Cowboy is a web server built in Erlang. It's a production ready server and not just a handy tool for development environment like . Currently Cowboy is the only supported Erlang web server by Phoenix. In this post, we shall see how to run a simple app using just Cowboy in your Elixir app. Understanding how Cowboy works and knowing the functionalities that it gives can form a strong foundation of understanding how Phoenix works and its internals.
Minimal code to start a Cowboy server and say Hello World!
Let's start with creating a new Elixir app that will print "Hello World!" when you visit .
Open up and add Cowboy as a dependency.
Once the downloading of dependencies and compilation is complete, run iex shell using mix.
This starts shell with all the compiled code of our application and its dependencies loaded. We don't have any code in our application yet but we do have mentioned as a dependency and we want it to be compiled and loaded in our iex shell.
Once in shell, define the following module and run the code below. I admit that the code is quite cryptic but don't worry, I am going to explain it shortly. So go ahead and copy paste the following code in your shell.
Now open up and behold the glamorous text of every programmer.
To understand what we just did, we need to know more about Cowboy server. Cowboy is an Erlang web server similar to Nginx or Apache. However there are quite a few important differences.
- The web server maps http requests to an Erlang module.
- The web server is started by the application and not by the operating system.
A successful configuration of a Cowboy server to provide a response involves
- Defining the Cowboy router
- Compiling the router
- Defining the Cowboy Handler module
- Sending response in our Cowboy Handler
- Starting the Cowboy server with our compiled routes
Defining the Cowboy router
This is the most cryptic part of all, but understanding it is not as difficult as it seems.
Let's crack it from the center. is Cowboy's way of saying for any given path, use the module as the handler and pass the value .
So each path in Cowboy is a tuple with three elements of the format . Since an application might need to handle multiple paths, Cowboy wants the paths information as a list.
Our simple Cowboy application, we need only one wildcard path as we want to display a static message to all paths.
Then to understand further, let's go a level above the paths in our dispatch_config.
This outer layer of tuple contains the host information. Again is a wildcard but matching any host. So the host layer tuple is of the format . Since there can be multiple hosts per machine, we provide a list here again. Following example makes the entire routing structure clear.
Imagine we have two different domains and pointed to the same machine. On we need and pages, and on we need and pages. A configuration for such a system will look this:
Compiling the router
To compile our router, all that you need to do is call with our list of routes. Compiling of routes enables Cowboy to match routes more efficiently.
Defining the Cowboy Handler module
The handler modules need to define the following three functions to be eligible to handle a Cowboy connection. In our CowboyHandler module above, we have defined the following three functions. Without any one of these three functions defined in your Handler module, Cowboy will not start.
Sending response in our Cowboy Handler.
The main function where the response goes out is the and it needs to send out the response to Cowboy process by calling .
Starting the Cowboy server
Nginx or Apache web servers are started by the host operating system. So when you deploy a PHP or Rails app, you application code has nothing to do with Nginx or Apache. You application does not start or stop Nginx server and you don't run an instance of Nginx for each of your application. If you have 10 PHP applications, you don't run 10 separate copies of Nginx for these 10 web applications.
With Cowboy, you web application need to start it as part of your application booting process and has to kill it when your application stops.
The below code that you have run already is responsible for starting Cowboy server.
The code is starting 100 processes of Cowboy to handle multiple request and is listening at port 8080.
To start the Cowboy server with our compiled routes, we need more details apart from the compiled router.
Are you using http or https? How many Cowboy processes do you need to start? Which port does Cowboy listen for request?
function starts the Cowboy server with all required configuration.
- - you can provide any atom. Ranch, a dependency of Cowboy makes use of this atom to name the process that it manages.
- - how many Cowboy process do you need for your application to handle multiple concurrent requests?
- - there are many tcp options that you can configure when you start the server. One such is configuring the port number on which your server listens for request. Since there are many options, the data type is a list of tuple with each tuple configuring one tcp option.
- - these are data that are passed to Cowboy for managing a request. It contains the routing information.
With this above knowledge, we can now configure our Cowboy server:
To recap, our entire code looks like this to display the simple "Hello World!" message. This entire code has to be run on shell.
We could improve on this by having the code saved in a module file and starting the Cowboy server as part of our app starting process. I leave it as an exercise for you to handle it.
Why do you need Phoenix?
Can you build your app entirely on Cowboy using the method described above? If so what do you need?
- You might need more specific routes than one that we configured. Yes, this can be done. The router will look more complex and difficult to manage but possible.
- You will need support for more HTTP verbs. All routes that we saw above are HTTP GET requests. We need support for POST, PUT etc for a real case application. Again, Cowboy provides this support but it just needs modification to the way we started our Cowboy server.
- You need models and 'activerecord-like' features. For this you can use Ecto package (AR equivalent in Elixir).
- You need templates, helper functions to do many of the common web stuff like getting and setting cookies, parsing headers, csrf checks etc. Cowboy doesn't do all of these.
- Lastly you need to have good understanding of Erlang so that you can read Cowboy documentation which by all means is very sparse compared to the rich docs in Elixir ecosystem.
Ok. Solutions exist but do you want to take that route? Unless you are venturing out to build another Phoenix framework or you are a masochist, using Phoenix library is the right choice to focus on getting things done and to keep your sanity level in check.
Here is a non-exhaustive list of what Phoenix provides in comparison with Cowboy?
- Phoenix uses a library called Plug, that takes care of low-level plumbing with Cowboy and frees you from worrying about how to configure Cowboy.
- Your router configurations are much cleaner in Phoenix. Thanks for meta programming in Elixir, you can write routes without making any one mad.
- Plug provides several small independent functionalities that are common in web so you can pick and choose what you need with no bloat.
- Phoenix which is build on top of Plug, provides a clean and uniform way to deal with request and if you could understand how Plug works, you can understand most of Phoenix.
- With Phoenix, you can get most of your tasks done without touching a line of Erlang code and do everything with Elixir. That's a great boost to productivity.
That brings us to the end of a long post. Hope you enjoyed it. If you have any questions please feel free to comment below and I will do my best to answer them all.