Sometimes I miss the old days of Sinatra. It was so simple to build a really simple server, that we can do it in less than ten lines into two files, the Gemfile
and the server.rb
file.
We need to work a little more than expected with Elixir, but it's doable, and with a plus, it's not hard to bake tests inside your script.
Thanks to Mix.install/2
that is available since Elixir v1.12.0, its possible even to make it in one single file. Just place the snippet bellow in a single file, for example, server.exs
# Place this content on server.exs file
Mix.install([
{:plug_cowboy, "~> 2.0"}
])
defmodule Server do
use Plug.Router
plug(:match)
plug(:dispatch)
get "/hello-world" do
send_resp(conn, 200, "Hello World!")
end
match _ do
send_resp(conn, 404, "Nothing to see here")
end
end
ExUnit.start(autorun: false)
defmodule ServerTest do
use ExUnit.Case, async: true
use Plug.Test
@opts Server.init([])
test "returns hello world" do
# Create a test connection
conn = conn(:get, "/hello-world")
# Invoke the plug
conn = Server.call(conn, @opts)
# Assert the response and status
assert conn.state == :sent
assert conn.status == 200
assert conn.resp_body == "Hello World!"
end
test "returns 404 to any another route" do
for path <- ["/foo", "/bar"] do
conn = conn(:get, path)
conn = Server.call(conn, @opts)
assert conn.state == :sent
assert conn.status == 404
assert conn.resp_body == "Nothing to see here"
end
end
end
case ExUnit.run() do
%{failures: 0} ->
Plug.Cowboy.http(Server, [], port: 4000)
System.no_halt(true)
_ ->
:error
end
And now just call in your shell:
elixir server.exs
Visit your browser at http://localhost:4000/hello-world to see the result.
This is another small and interesting tip to the mix of useful things that we can do with Elixir.
Happy Hacking Folks!
Top comments (11)
As far as simple single code file servers go, I really don't think it gets more basic than Express tbh 🤷♂️
Well, in Elixir's defense, please note this script includes the server AND the tests for it, the server per se could be done just with:
Also, this is a totally standalone script, it does not require ANYTHING else besides you having Elixir installed and calling
elixir server.exs
, as the dependencies are downloaded for you with the functionMix.install
on the beginning of the file, so you could totally just download that script and run it. While with express, AFAIR you need to install express too, which either involves anpm -g express
(that might lead to problems with different express versions) or having a folder structure and apackage.json
, which is not that simple TBH.Definitely good points! I suppose my suggestion would have to include something unsavory like exec("npm I express@latest -g") to truly get it into a true single file that you can run with just Node installed which just... yeah, yuck.
I guess I could make that point that Deno has this functionality built in if I wanted to be that kind of JS/TS fanboy but then we're out of the "simplistic" and well documented context.
For the record, I dig Elixir + Phoenix. I'm not a Node dev strictly (though it's what clients have most commonly been asking for, in my experience), I just think it's the defacto for most simple tooling.
Yeah, deno is a nice project, hopefully it gets traction as it solves a lot of the problems node has. But I'm sticking with Elixir either way. 😄
Your comment got me thinking though: is this something we want? I mean, is there a valid use case for a very simple server like this? Cause if there is, maybe there is room for another library on top of
plug
that would make all this simpler. Maybe even improved tooling around single-file scripts servers IDK 🤔I think there's a use-case for incredibly simple tooling. I mean... the Docker build for deploying this server to production just has to have Elixir installed and that's pretty cool!
Nodejs is not very industry pervasive... Php is 70% of the internet. You might think nodejs is pervasive because the majority of loud people use. But they realy make up a very small minority of the internet. What you see is not all there is. And coming here on a Elixir post and telling a person to mention something is such a childish move.
nibblestew.blogspot.com/2017/04/wh...
I ended up on this thread because of a Google News link to a previous title or a generated title that just said something along the lines of "A simple scriptable server." When I saw it was Elixir, I just felt like "oh that just doesn't seem like the simplest way to define a server in a single code file." It also references missing older technologies in Ruby so it appeared that the topic of other languages were on the table.
Also, I think the more relevant numbers are what percentage of jobs are using what at the moment. Or you can look at the Github developer survey where JavaScript has been the most popular language since 2014. Even if that's not all Node, it's still a nod to the accessibility of that language to developers. So on the topic of simplicity, I felt it was relevant.
Also I think that "70% of the internet is PHP" myth is partially out of date and partially driven up by CMS services which use it in the backend like WordPress.
Yes, it's really interesting to discuss the missing points of our day to day tools and it's why I brough Ruby, a technology that I'm very familiar and linked it with Elixir because just happened to be my current history of transitioning from Ruby to Elixir, a path walked by a lot of people, so I think that the subject reasonates better to people with this background. Despite that, Elixir is niche in the industry and even Ruby is kind of niche, even after so many years with big companies using it, when compared to PHP, and also NodeJS.
Yes sure, but anyways, Nodejs is not my tool of preference, never was.
That's fair but it's incredibly industry pervasive these days. But I mean obviously Elixir has a performance advantage, but if you're going with "as simple as possible," I think the most common tool is worth talking about.
Absolutely, and seems that there is a lot of examples of how to make a good usage of the most common tool on the internet, but interestingly I just find few showing how to setup a simple server in Elixir. This is the beauty of internet, there is space to every subject that can satisfy every audience.