DEV Community

Cover image for Entendendo Plugs em Elixir
Paulo Castro
Paulo Castro

Posted on • Edited on

43 26

Entendendo Plugs em Elixir

Introdução

A motivação do Artigo veio através de uma dificuldade que tive estudando Plugs em Elixir, o conteúdo não exemplificava e/ou explicava muito bem o funcionamento desse tipo de componente, e após muito estudo consegui uma forma interessante para entender tudo isso, e nada melhor do que compartilhar esse estudo!

Dessa forma, artigo de hoje tem o intuito de explicar o funcionamento dos Plugs em Elixir por meio das seguintes etapas abaixo. No entanto, é de SUMA importância que você tenha conhecimento do protocolo HTTP e do ciclo de vida das requisições, pois isso não será abordado no texto abaixo:

  1. Middlewares: Um breve resumo

    1. Tipos comuns de middlewares utilizados em Elixir
  2. Plugs em Elixir!

    1. Elementos e caminhos de um Plug
  3. Tipos de Plugs em Elixir

    1. Function Plugs
    2. Module Plugs
  4. Plug Pipelines

1 - Middlewares: Um breve resumo

Middleware é um tipo de software que gerencia dados e informações de um determinado tipo de aplicação, seja ela um sistema de mensageria, autenticação, API, dentre outros. Dessa forma, o middleware atua como uma "ponte" entre os processos do software, possibilitando a criação de aplicações mais legíveis e eficientes, uma vez que o desenvolvedor entenda todos os processos de seu middleware, onde as conexões e dados do usuário final sejam tratadas de forma integral e legível pelo programa.

1.1 - Tipos comuns de middlewares utilizados em Elixir

  • Integração abrangente: Esse middleware possibilita conectar sistemas internos e externos da aplicação, facilitando a tratativa dos dados recebidos, temos como exemplo uma linha de autenticação por token, onde o usuário envia a primeira requisição com seus dados e em seguida ganha um "Token" para continuar navegando em outras áreas de um determinado site. Em elixir temos libs que disponibilizam plugs para isso.

  • API's: As nossas boas e velhas APi's também são tipos de middlewares, uma vez que as mesmas também podem ser ferramentas integradas por meio de protocolos, transmitindo e/ou tratando dados para uma aplicação e podendo conectar os produtos e serviços de um software.

Elixir-plug-example

2 - Plugs em Elixir!

Em Elixir, o Plug é o que possibilita diferentes frameworks se comunicarem com diferentes servidores na VM do Erlang, atuando como um Middleware. Entender os Plugs é algo vital para um bom desenvolvedor Elixir, uma vez que grande parte do ecossistema de uma aplicação e seus frameworks é feita por meio de Plugs.

Os Plugs vão interagir em todas as etapas de uma aplicação, sejam elas controllers, endpoints ou routers, e internamente, todos são plugs.

A intenção principal de um Plug é unificar o conceito de "Connection" (isso não será traduzido, pois, será tratado como elementos e parâmetros em Elixir, e é uma convenção abreviar tal parâmetro) ou "Conn". Dessa forma, o Plug difere-se de outros middlewares que utilizam desse mesmo sistema de Connections, pois internamente ele não separa a requisição da resposta.

2.1 - Elementos e caminhos de um Plug

É possível pensar em um Plug como um trecho do código que recebe uma estrutura de dados, transforma-a e retorna a mesma estrutura, porém, com algum tipo de transformação. A estrutura principal recebida pelo Plug é a "Connection", que representa tudo em uma requisição.

Desse modo, ao receber a Connection por meio da estrutura de dados %{} - "struct", a mesma será transformada progressivamente por meio do que chamamos de "Plug pipeline" até a resposta final que precisamos.

Essa Connection que utilizaremos sempre é chamada de %Plug.Conn{}, uma struct onde armazenaremos as informações da nossa requisição, você pode consultar a documentação da mesma aqui.

3 - Tipos de Plugs em Elixir

Em seu nível mais simples, os Plugs dividem-se em duas formas: Function Plugs e Module Plugs.

3.1 - Function Plugs

Para atuar como um Plug, uma função precisa de duas coisas:

  1. Aceitar uma Connection struct ( %Plug.Conn{} ).

  2. Retornar uma Connection struct

Toda função que receber e retornar tais parâmetros pode ser chamada Function plug.

Temos como exemplo:

def connection_example(conn, _opts) do
  conn
end
Enter fullscreen mode Exit fullscreen mode

Explicando o código:

Elementos:

  • conn: struct %Plug.Conn{}.

  • _opts: abreviação para "options", como não será utilizada e, por convenção em elixir, é colocado um underscore ( _ ) para ignorar os valores.

Comportamento:

  • Receberá a connection e as options (que não utilizaremos).

3.2 - Module Plugs

É considerado Module Plug tudo aquilo que implementa as duas funções: init/1 e call/2:

defmodule PlugExample do
  def init(opts) do
    opts
  end

  def call(conn, opts) do
    conn
  end
end
Enter fullscreen mode Exit fullscreen mode

Explicando o código:

Elementos:

  • função init/1

  • função call/2

Comportamento:

  • init receberá um parâmetro (options) e retornará o parâmetro recebido.

  • call receberá dois parâmetros: a connection e as options de init/1, agilizando muito o processo de execução do programa.

    • Curiosidade: init/1 é executada enquanto o programa é compilado, enquanto call/2 acontece enquanto o programa está sendo executado.

Um exemplo

Para não deixar esse artigo gigante, você pode consultar um exemplo funcional de um MODULE PLUG no meu github

Plug pipelines

Os Plugs começam a tomar sentido quando começamos a utilizar pipelines, que nada mais é do que um jeito de aninhar os Plugs, cada um fazendo uma pequena tarefa, transformando os dados e mandando-os para o próximo Plug de forma sequencial.

Tal coisa é muito utilizada no Phoenix, o framework para aplicações Web do Elixir, de modo que temos a seguinte pipeline como padrão:

pipeline :browser do
  plug :accepts, ["html"]
  plug :fetch_session
  plug :fetch_flash
  plug :protect_from_forgery
  plug :put_secure_browser_headers
end
Enter fullscreen mode Exit fullscreen mode

Dessa forma, cada requisição terá como retorno uma Connection modificada, que será passada para outros plugs até chegarmos a uma resposta final.

Conclusão

Com esse artigo, é possível entender o que é um middleware, Plugs em Elixir, Tipos de Plugs e Plug pipelines, não será possível, nessa ocasião, a construção de um Plug em Phoenix. No entanto, farei um artigo futuramente detalhando passo-a-passo a criação de um Plug desde o mix phx.new até o término do código.

No mais, espero que eu tenha conseguido clarear um pouco a ideia dos Plugs, e qualquer dúvida e/ou correções é possível me contatar no twitter!

Image of Docusign

🛠️ Bring your solution into Docusign. Reach over 1.6M customers.

Docusign is now extensible. Overcome challenges with disconnected products and inaccessible data by bringing your solutions into Docusign and publishing to 1.6M customers in the App Center.

Learn more

Top comments (9)

Collapse
 
wlsf profile image
Willian Frantz

Muito massa o texto maninho, parabéns e obrigado por compartilhar o conteúdo!

Uma das coisas que mais admiro no Elixir, é esse princípio de Composability que é muito utilizado, como no exemplo que você deu de aninhar plugs em uma pipeline, que também pode ser usado no Ecto para aninhar queries, ou até mesmo no Elixir com o pipe operator!

Collapse
 
cyytrus profile image
Paulo Castro

Muito obrigado pelo feedback, irmão! e agradeço mais ainda por ter me incentivado a buscar esse conteúdo e trazê-lo em português!

Exatamente! Composability em Elixir é incrível em todas as formas!

Collapse
 
rohlacanna profile image
Rômulo Silva

Ótimo artigo! Parabéns Paulo, ficou realmente muito bom! :')

Collapse
 
cyytrus profile image
Paulo Castro

Agradeço demais pelo feedback, Rômulo! Você é uma inspiração p mim!

Collapse
 
uberlandino profile image
Douglas Alves

Parabéns pelo artigo! Didática impecavel, sempre.

Collapse
 
cyytrus profile image
Paulo Castro

Valeuuuu Douglão, você é o melhor!

Collapse
 
bronen profile image
BRonen

incrivel explicação👌👏

Collapse
 
cyytrus profile image
Paulo Castro

Mt obg!

Collapse
 
jvmartyns profile image
João Vitor Martins Araújo

Muito bom!

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

👋 Kindness is contagious

Discover a treasure trove of wisdom within this insightful piece, highly respected in the nurturing DEV Community enviroment. Developers, whether novice or expert, are encouraged to participate and add to our shared knowledge basin.

A simple "thank you" can illuminate someone's day. Express your appreciation in the comments section!

On DEV, sharing ideas smoothens our journey and strengthens our community ties. Learn something useful? Offering a quick thanks to the author is deeply appreciated.

Okay