Packages
plug
0.5.0
1.20.3
1.20.2
1.20.1
retired
1.20.0
retired
1.19.5
1.19.4
1.19.3
1.19.2
1.19.1
1.19.0
1.18.5
1.18.4
1.18.3
1.18.2
1.18.1
1.18.0
1.17.4
1.17.3
1.17.2
1.17.1
1.17.0
1.16.6
1.16.5
1.16.4
1.16.3
1.16.2
1.16.1
1.16.0
1.15.6
1.15.5
1.15.4
1.15.3
1.15.2
1.15.1
1.15.0
1.14.2
1.14.1
1.14.0
1.13.6
1.13.5
1.13.4
1.13.3
1.13.2
1.13.1
retired
1.13.0
retired
1.12.1
1.12.0
1.11.1
1.11.0
1.10.4
1.10.3
1.10.2
1.10.1
1.10.0
1.9.0
1.8.3
1.8.2
1.8.1
1.8.0
1.7.2
1.7.1
1.7.0
1.6.4
1.6.3
1.6.2
1.6.1
1.6.0
1.5.1
1.5.0
1.5.0-rc.2
1.5.0-rc.1
1.5.0-rc.0
1.4.5
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.4.0-rc.0
1.3.6
1.3.5
1.3.4
1.3.3
1.3.2
1.3.1
1.3.0
1.2.6
1.2.5
1.2.4
1.2.3
1.2.2
1.2.1
1.2.0
1.2.0-rc.0
1.1.9
1.1.8
1.1.7
1.1.6
1.1.5
1.1.4
1.1.3
1.1.2
1.1.1
1.1.0
1.0.6
1.0.5
1.0.4
1.0.3
1.0.2
1.0.1
1.0.0
0.14.0
0.13.1
0.13.0
0.12.2
0.12.1
0.12.0
0.11.3
0.11.2
0.11.1
0.11.0
0.10.0
0.9.0
0.8.4
0.8.3
0.8.2
0.8.1
0.8.0
0.7.0
0.6.0
0.5.3
0.5.2
0.5.1
0.5.0
0.4.4
0.4.3
0.4.2
0.4.1
Compose web applications with functions
Security advisory:
This version has known vulnerabilities.
View advisories
Current section
Files
Jump to
Current section
Files
README.md
# Plug
[](https://travis-ci.org/elixir-lang/plug)
Plug is:
1. A specification for composable modules in between web applications
2. Connection adapters for different web servers in the Erlang VM
[Documentation for Plug is available online](http://elixir-lang.org/docs/plug/).
## Hello world
```elixir
defmodule MyPlug do
import Plug.Conn
def init(options) do
# initialize options
options
end
def call(conn, _opts) do
conn
|> put_resp_content_type("text/plain")
|> send_resp(200, "Hello world")
end
end
IO.puts "Running MyPlug with Cowboy on http://localhost:4000"
Plug.Adapters.Cowboy.http MyPlug, []
```
The snippet above shows a very simple example on how to use Plug. Save that snippet to a file and run it inside the plug application with:
mix run --no-halt path/to/file.exs
Access "http://localhost:4000" and we are done!
## Installation
You can use plug in your projects in two steps:
1. Add plug and your webserver of choice (currently cowboy) to your `mix.exs` dependencies:
```elixir
def deps do
[{:cowboy, github: "extend/cowboy"},
{:plug, "~> 0.4.2"}]
end
```
2. List both `:cowboy` and `:plug` as your application dependencies:
```elixir
def application do
[applications: [:cowboy, :plug]]
end
```
Note: if you are using Elixir master, please use Plug master (from git) as well.
## The Plug.Conn
In the hello world example, we defined our first plug. What is a plug after all?
A plug takes two shapes. It is a function that receives a connection and a set of options as arguments and returns the connection or it is a module that provides an `init/1` function to initialize options and implement the `call/2` function, receiving the connection and the initialized options, and returning the connection.
As per the specification above, a connection is represented by the `Plug.Conn` record ([docs](http://elixir-lang.org/docs/plug/Plug.Conn.html)):
```elixir
%Plug.Conn{host: "www.example.com",
path_info: ["bar", "baz"],
...}
```
Data can be read directly from the record and also pattern matched on. However, whenever you need to manipulate the record, you must use the functions defined in the `Plug.Conn` module ([docs](http://elixir-lang.org/docs/plug/Plug.Conn.html)). In our example, both `put_resp_content_type/2` and `send_resp/3` are defined in `Plug.Conn`.
Remember that, as everything else in Elixir, **a connection is immutable**, so every manipulation returns a new copy of the connection:
```elixir
conn = put_resp_content_type(conn, "text/plain")
conn = send_resp(conn, 200, "ok")
conn
```
Finally, keep in mind that a connection is a **direct interface to the underlying web server**. When you call `send_resp/3` above, it will immediately send the given status and body back to the client. This makes features like streaming a breeze to work with.
## Testing plugs and applications
Plug ships with a `Plug.Test` module ([docs](http://elixir-lang.org/docs/plug/Plug.Test.html)) that makes testing your plugs easy. Here is how we can test our hello world example:
```elixir
defmodule MyPlugTest do
use ExUnit.Case, async: true
use Plug.Test
@opts MyPlug.init([])
test "returns hello world" do
# Create a test connection
conn = conn(:get, "/")
# Invoke the plug
conn = MyPlug.call(conn, @opts)
# Assert the response and status
assert conn.state == :sent
assert conn.status == 200
assert conn.resp_body == "Hello world"
end
end
```
## The Plug Router
The Plug router allows developers to quickly match on incoming requests and perform some action:
```elixir
defmodule AppRouter do
import Plug.Conn
use Plug.Router
plug :match
plug :dispatch
get "/hello" do
send_resp(conn, 200, "world")
end
match _ do
send_resp(conn, 404, "oops")
end
end
```
The router is a plug, which means it can be invoked as:
```elixir
AppRouter.call(conn, AppRouter.init([]))
```
Each route needs to return the connection as per the Plug specification.
Note `Plug.Router` compiles all of your routes into a single function and relies on the Erlang VM to optimize the underlying routes into a tree lookup, instead of a linear lookup that would instead match route-per-route. This means route lookups are extremely fast in Plug!
This also means that a catch all `match` is recommended to be defined, as in the example above, otherwise routing fails with a function clause error (as it would in any regular Elixir function).
### Available Plugs
This project aims to ship with different plugs that can be re-used accross applications:
* `Plug.Head` ([docs](http://elixir-lang.org/docs/plug/Plug.Head.html)) - converts HEAD requests to GET requests;
* `Plug.MethodOverride` ([docs](http://elixir-lang.org/docs/plug/Plug.MethodOverride.html)) - overrides a request method with one specified in headers;
* `Plug.Parsers` ([docs](http://elixir-lang.org/docs/plug/Plug.Parsers.html)) - responsible for parsing the request body given its content-type;
* `Plug.Session` ([docs](http://elixir-lang.org/docs/plug/Plug.Session.html)) - handles session management and storage;
* `Plug.Static` ([docs](http://elixir-lang.org/docs/plug/Plug.Static.html)) - serves static files;
## License
Plug source code is released under Apache 2 License.
Check LICENSE file for more information.