Skip to content

Commit

Permalink
Improve Plug README
Browse files Browse the repository at this point in the history
  • Loading branch information
josevalim committed Sep 5, 2024
1 parent d8c1736 commit 0fa1f92
Showing 1 changed file with 44 additions and 36 deletions.
80 changes: 44 additions & 36 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Plug is:
1. A specification for composing web applications with functions
2. Connection adapters for different web servers in the Erlang VM

[Documentation for Plug is available online](http://hexdocs.pm/plug/).
In other words, Plug allows you to build web applications from small pieces and run them on different web servers. Plug is used by web frameworks such as [Phoenix](https://phoenixframework.org) to manage requests, responses, and websockets. This documentation will show some high-level examples and introduce the Plug's main building blocks.

## Installation

Expand Down Expand Up @@ -68,6 +68,10 @@ Process.sleep(:infinity)
Save that snippet to a file and execute it as `elixir hello_world.exs`.
Access <http://localhost:4000/> and you should be greeted!

In the example above, we wrote our first **module plug**, called `MyPlug`.
Module plugs must define the `init/1` function and the `call/2` function.
`call/2` is invoked with the connection and the options returned by `init/1`.

## Hello world: websockets

Plug v1.14 includes a connection `upgrade` API, which means it provides WebSocket
Expand Down Expand Up @@ -131,9 +135,13 @@ Save that snippet to a file and execute it as `elixir websockets.exs`.
Access <http://localhost:4000/> and you should see messages in your browser
console.

As you can see, Plug abstracts the different webservers. When booting
up your application, the difference is between choosing Plug.Cowboy
or Bandit.
This time, we used `Plug.Router`, which allows us to define the routes
used by our web application and a series of steps/plugs, such as
`plug Plug.Logger`, to be executed on every request.

Furthermore, as you can see, Plug abstracts the different webservers.
When booting up your application, the difference is between choosing
`Plug.Cowboy` or `Bandit`.

For now, we have directly started the server in a throw-away supervisor but,
for production deployments, you want to start them in application
Expand Down Expand Up @@ -185,32 +193,20 @@ Finally create `lib/my_app/my_plug.ex` with the `MyPlug` module.

Now run `mix run --no-halt` and it will start your application with a web server running at <http://localhost:4001>.

## Supported Versions
## Plugs and the `Plug.Conn` struct

| Branch | Support |
|--------|--------------------------|
| v1.15 | Bug fixes |
| v1.14 | Security patches only |
| v1.13 | Security patches only |
| v1.12 | Security patches only |
| v1.11 | Security patches only |
| v1.10 | Security patches only |
| v1.9 | Unsupported from 10/2023 |
| v1.8 | Unsupported from 01/2023 |
| v1.7 | Unsupported from 01/2022 |
| v1.6 | Unsupported from 01/2022 |
| v1.5 | Unsupported from 03/2021 |
| v1.4 | Unsupported from 12/2018 |
| v1.3 | Unsupported from 12/2018 |
| v1.2 | Unsupported from 06/2018 |
| v1.1 | Unsupported from 01/2018 |
| v1.0 | Unsupported from 05/2017 |
In the hello world example, we defined our first plug called `MyPlug`. There are two types of plugs, module plugs and function plugs.

## The `Plug.Conn` struct
A module plug implements an `init/1` function to initialize the options and a `call/2` function which receives the connection and initialized options and returns the connection:

In the hello world example, we defined our first plug. What is a plug after all?
```elixir
defmodule MyPlug do
def init([]), do: false
def call(conn, _opts), do: conn
end
```

A plug takes two shapes. A function plug receives a connection and a set of options as arguments and returns the connection:
A function plug takes the connection, a set of options as arguments, and returns the connection:

```elixir
def hello_world_plug(conn, _opts) do
Expand All @@ -220,16 +216,7 @@ def hello_world_plug(conn, _opts) do
end
```

A module plug implements an `init/1` function to initialize the options and a `call/2` function which receives the connection and initialized options and returns the connection:

```elixir
defmodule MyPlug do
def init([]), do: false
def call(conn, _opts), do: conn
end
```

As per the specification above, a connection is represented by the `Plug.Conn` struct:
A connection is represented by the `%Plug.Conn{}` struct:

```elixir
%Plug.Conn{
Expand Down Expand Up @@ -352,6 +339,27 @@ If you are planning to contribute documentation, [please check our best practice

Finally, remember all interactions in our official spaces follow our [Code of Conduct][code-of-conduct].

## Supported Versions

| Branch | Support |
|--------|--------------------------|
| v1.15 | Bug fixes |
| v1.14 | Security patches only |
| v1.13 | Security patches only |
| v1.12 | Security patches only |
| v1.11 | Security patches only |
| v1.10 | Security patches only |
| v1.9 | Unsupported from 10/2023 |
| v1.8 | Unsupported from 01/2023 |
| v1.7 | Unsupported from 01/2022 |
| v1.6 | Unsupported from 01/2022 |
| v1.5 | Unsupported from 03/2021 |
| v1.4 | Unsupported from 12/2018 |
| v1.3 | Unsupported from 12/2018 |
| v1.2 | Unsupported from 06/2018 |
| v1.1 | Unsupported from 01/2018 |
| v1.0 | Unsupported from 05/2017 |

## License

Plug source code is released under Apache License 2.0.
Expand Down

0 comments on commit 0fa1f92

Please sign in to comment.