Elixir Server: Hello World & User IP Tutorial
Hey guys! Today, we're diving into building a simple yet powerful Elixir server that does two cool things: it greets users with a friendly "Hello World" message and, even cooler, it tells them their IP address. This is a fantastic project for anyone getting started with Elixir and wanting to understand how to handle HTTP requests. So, let's get started!
Setting Up Our Elixir Project
First things first, we need to set up our Elixir project. If you haven't already got Elixir and Erlang installed, now's the time to do it. You can find the installation instructions on the official Elixir website. Once you're all set, open up your terminal and let's create a new project.
mix new hello_world_server
cd hello_world_server
This command uses Mix, Elixir's build tool, to generate a new project named hello_world_server
. We then navigate into the project directory. Inside, you'll see a bunch of files and folders. The main ones we'll be working with are mix.exs
(our project configuration) and the lib
directory where our Elixir code will live.
Adding Dependencies
To handle HTTP requests, we're going to use a library called Plug
. Plug is a specification for building web applications in Elixir, and it's super versatile. We'll also use Cowboy
, which is a web server adapter for Plug. To add these dependencies, we need to modify our mix.exs
file.
Open up mix.exs
and find the deps
function. It should look something like this:
defp deps do
[
# {:dep_from_hexpm, ">= 0.0.0"},
# {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git"}
]
end
Let's add Plug and Cowboy as dependencies:
defp deps do
[
{:plug, "~> 2.0"},
{:cowboy, "~> 2.0"}
]
end
Here, we're specifying that we want Plug version 2.0 or higher and Cowboy version 2.0 or higher. Save the file, and then run the following command in your terminal to fetch the dependencies:
mix deps.get
This command tells Mix to download and install the dependencies we just added.
Configuring Our Application
Next, we need to configure our application to use Plug and Cowboy. Still in mix.exs
, find the application
function. It might look like this:
def application do
[
extra_applications: [:logger]
]
end
We need to tell our application to start Cowboy when it starts. To do this, we'll add :cowboy
to the extra_applications
list:
def application do
[
extra_applications: [:logger, :cowboy]
]
end
Save the file. Now, our application knows to start Cowboy when it starts up.
Creating Our Plug
Now comes the fun part: writing the code that handles the HTTP requests! We'll create a new module that implements the Plug behaviour. This module will be responsible for receiving requests, processing them, and sending back responses.
Inside the lib
directory, create a new file named hello_world_server.ex
. This is where our Plug module will live. Open it up and let's start coding:
defmodule HelloWorldServer do
use Plug.Router
plug :match
plug :dispatch
get "/", do:
send_resp(conn, 200, "Hello, World!")
get "/ip", do:
ip = Plug.Conn.get_req_header(conn, "x-forwarded-for") |> List.first() || Plug.Conn.remote_ip(conn) |> Tuple.to_list() |> List.first() |> to_string()
send_resp(conn, 200, "Your IP address is: #{ip}")
match _ do
send_resp(conn, 404, "Not Found")
end
end
Let's break down what's happening here:
defmodule HelloWorldServer do
: This defines our module namedHelloWorldServer
. This is where all our server logic will reside.use Plug.Router
: This line is crucial. It brings in thePlug.Router
functionality, which allows us to define routes for our server. Think of routes as different paths on your website or application (like/
or/ip
).plug :match
andplug :dispatch
: These are Plug's way of saying, "Hey, let's match the incoming request to a route and then dispatch it to the appropriate handler function." This is the heart of how Plug handles requests.get "/", do:
: This is where we define our first route. Theget
macro tells Plug that this route should handle HTTP GET requests to the root path (/
). When a user visits the main page of our server, this is the code that will be executed.send_resp(conn, 200, "Hello, World!")
: This is the action taken when someone visits the root path.send_resp
is a function provided by Plug that sends a response back to the client. Here, we're sending a 200 OK status code (which means everything's fine) and the message "Hello, World!". This is the classic greeting!get "/ip", do:
: This defines another route, this time for the/ip
path. When a user visits/ip
, we want to show them their IP address. This is where things get a little more interesting.ip = ...
: This line is the core of our IP address retrieval logic. Let's break it down further:Plug.Conn.get_req_header(conn, "x-forwarded-for")
: This tries to get theX-Forwarded-For
header from the request. This header is often used by proxies and load balancers to pass along the original IP address of the client. If the server is behind a proxy, this is the best way to get the user's IP.|> List.first()
: TheX-Forwarded-For
header can contain a list of IPs, so we take the first one.|| Plug.Conn.remote_ip(conn)
: If theX-Forwarded-For
header is not present (e.g., the user isn't behind a proxy), we fall back to usingPlug.Conn.remote_ip(conn)
. This gives us the IP address of the direct connection to the server.|> Tuple.to_list() |> List.first()
:Plug.Conn.remote_ip
returns the IP address as a tuple. We convert it to a list and take the first element to get the IP address in a usable format.|> to_string()
: Finally, we convert the IP address to a string so we can include it in our response.
send_resp(conn, 200, "Your IP address is: #{ip}")
: Just like before, we're sending a 200 OK response, but this time with a message that includes the user's IP address.match _ do
: This is a catch-all route. The_
means "anything that doesn't match the previous routes." This is useful for handling cases where a user tries to visit a path that doesn't exist on our server.send_resp(conn, 404, "Not Found")
: Here, we're sending a 404 Not Found status code, which is the standard way to tell a user that the page they're looking for doesn't exist.
Save the hello_world_server.ex
file. We're almost there!
Starting the Server
We have our Plug module, but we need to tell Cowboy to use it. To do this, we'll modify the lib/hello_world_server/application.ex
file. This file defines our application's behaviour, including how it starts and stops.
Open up lib/hello_world_server/application.ex
. You'll see a start
function that looks something like this:
def start(_type, _args) do
children = [
# Supervisor.child_spec(HelloWorldServer.Worker, arg: 1)
]
opts = [strategy: :one_for_one, name: HelloWorldServer.Supervisor]
Supervisor.start_link(children, opts)
end
We need to add a child process to start Cowboy. This child process will listen for incoming HTTP requests and pass them to our HelloWorldServer
Plug.
Modify the children
list to include a call to Plug.Cowboy.child_spec
:
def start(_type, _args) do
children = [
{Plug.Cowboy, scheme: :http, plug: HelloWorldServer, options: [port: 4000]}
]
opts = [strategy: :one_for_one, name: HelloWorldServer.Supervisor]
Supervisor.start_link(children, opts)
end
Let's break down this new line:
{Plug.Cowboy, ...}
: This tells the supervisor to start aPlug.Cowboy
process.scheme: :http
: We're specifying that we want to use HTTP (not HTTPS) for our server.plug: HelloWorldServer
: This is the crucial part! We're telling Cowboy to use ourHelloWorldServer
module to handle incoming requests. This is how Cowboy knows to use our routing logic.options: [port: 4000]
: We're telling Cowboy to listen for connections on port 4000. This is the port that users will use to access our server.
Save the lib/hello_world_server/application.ex
file. Now, we're ready to start our server!
Running the Server
In your terminal, run the following command:
mix run --no-halt
This command starts our Elixir application. The --no-halt
flag tells Mix to keep the application running even after the initial startup tasks are complete. This is important because we want our server to keep running and listening for requests.
You should see some output in your terminal indicating that the server has started. If you see any errors, double-check your code and make sure you've followed all the steps correctly.
Testing the Server
Now that our server is running, let's test it out! Open up your web browser and navigate to http://localhost:4000
. You should see the message "Hello, World!" This means our basic route is working correctly.
Next, let's check the /ip
route. Navigate to http://localhost:4000/ip
. You should see a message that includes your IP address. If you're running the server on your local machine, you'll likely see 127.0.0.1
(the loopback address). If you're running it on a server, you'll see the server's public IP address.
Congratulations! You've successfully created an Elixir server that responds with "Hello World" and the user's IP address. How cool is that?
Making it Unique and SEO-Friendly
So, we've built our server, but how can we make this article stand out and attract more readers? Let's talk about making it unique and SEO-friendly.
Optimize Paragraphs
- Main Keywords at the Beginning: When writing each paragraph, try to include your main keywords right at the beginning. This helps search engines understand what the paragraph is about right away. For example, instead of saying, "This project is great for those starting with Elixir," you could say, "Elixir server creation is a fantastic project for those starting with Elixir." The keywords stand out, and it's clear what the paragraph is focusing on.
- Use Bold, Italic, and Strong Tags: These tags not only make your text look better but also help emphasize important information. Use
**bold**
for key phrases,*italic*
for emphasis, and<strong>strong</strong>
for crucial points that need to stand out. For instance, "Thesend_resp
function is essential for sending responses" highlights the importance of thesend_resp
function. - Paragraph Length: Aim for each content paragraph to contain at least 300 words. This might seem like a lot, but it ensures you're providing comprehensive information and covering the topic in detail. Longer paragraphs also give you more opportunities to naturally weave in keywords and provide context.
Rewrite for Humans
- Casual and Friendly Tone: Write like you're talking to a friend. Use casual language, slang, and personal anecdotes to make the content relatable. Instead of saying, "The user should navigate to..." try saying, "Okay guys, now head over to...". This makes the article feel more conversational and less like a technical manual.
- Focus on High-Quality Content: Ultimately, the best way to attract and retain readers is to provide valuable content. Focus on explaining concepts clearly, providing practical examples, and answering potential questions. Don't just aim for word count; aim for usefulness. If your content is helpful, people will want to read it, and search engines will recognize its value.
Proper Title Ordering
- Semantic Structure: Make sure your titles are properly ordered. Use
<h1>
for the main title,<h2>
for major sections,<h3>
for subsections, and so on. This helps organize your content logically and makes it easier for readers (and search engines) to understand the structure of your article. For example:<h1>Create an Elixir Server Responding with 'Hello World' and User IP</h1>
<h2>Setting Up Our Elixir Project</h2>
<h3>Adding Dependencies</h3>
- Title Length: Keep the title under 60 characters. This ensures it doesn't get cut off in search engine results and remains engaging at a glance. A concise title is more likely to grab attention and accurately reflect the content of your article.
Optimizing for SEO
- Keyword Research: Before writing, do some keyword research to find out what terms people are using to search for Elixir server tutorials. Tools like Google Keyword Planner or Ahrefs can help you identify relevant keywords. In our case, keywords like "Elixir server tutorial," "Hello World Elixir," and "get user IP Elixir" are good candidates.
- Keyword Placement: Once you have your keywords, strategically place them throughout your article. Include them in your title, headings, and body text. But don't stuff them in unnaturally; aim for a natural flow.
- Meta Descriptions: Write a compelling meta description for your article. This is the snippet of text that appears in search engine results below the title. It should accurately summarize your article and entice users to click.
- Internal and External Linking: Link to other relevant articles on your site (internal linking) and to authoritative sources on the web (external linking). This helps improve your site's overall SEO and provides additional value to your readers.
Conclusion
So, guys, that's how you create a basic Elixir server that responds with "Hello World" and the user's IP address! We've covered everything from setting up the project to writing the code and optimizing the article for SEO. Building this server is a great way to get your feet wet with Elixir and Plug. Plus, understanding how to get a user's IP address can be super useful for various applications.
Remember, the key to creating great content is to focus on providing value to your readers. Write clearly, explain things thoroughly, and make it fun! Keep experimenting with Elixir, and you'll be building amazing things in no time. Happy coding!