DEV Community

Cover image for Plugins and the pipeline
Daniel Widgren
Daniel Widgren

Posted on • Edited on

2 2

Plugins and the pipeline

Plugins

Image description

Plugins in Nova are modules that have a behaviour, these behaviours will be a part of the pipeline flow of a request.

-module(nova_correlation_plugin).

-behaviour(nova_plugin).

-export([pre_request/2,
         post_request/2,
         plugin_info/0]).

-include_lib("kernel/include/logger.hrl").

%%--------------------------------------------------------------------
%% @doc
%% Pre-request callback to either pick up correlation ID from request headers
%% or generate a new uuid correlation ID.
%% @end
%%--------------------------------------------------------------------

pre_request(Req0, Opts) ->
    CorrId = get_correlation_id(Req0, Opts),
    %% Update the logger's metadata with correlation-id
    ok = update_logger_metadata(CorrId, Opts),
    Req1 = cowboy_req:set_resp_header(<<"X-Correlation-ID">>, CorrId, Req0),
    Req = Req1#{correlation_id => CorrId},
    {ok, Req}.

post_request(Req, _) ->
    {ok, Req}.

plugin_info() ->
   {
     <<"nova_correlation_plugin">>,
     <<"0.2.0">>,
     <<"Nova team <info@novaframework.org">>,
     <<"Add X-Correlation-ID headers to response">>,
     []
    }.

get_correlation_id(Req, #{ request_correlation_header := CorrelationHeader }) ->
    case cowboy_req:header(CorrelationHeader, Req) of
        undefined ->
            uuid();
        CorrId ->
            CorrId
    end;

get_correlation_id(_Req, _Opts) ->
    uuid().

uuid() ->
    uuid:uuid_to_string(uuid:get_v4()).

update_logger_metadata(CorrId, Opts) ->
    LoggerKey = maps:get(logger_metadata_key, Opts, <<"correlation-id">>),
    logger:update_process_metadata(#{LoggerKey => CorrId}).
Enter fullscreen mode Exit fullscreen mode

This is an example plugin that will add a correlation ID to all your requests.

Pipeline

We can look at the flow of a request as a pipeline that will go into different plugins before and after it has done the controller code.

Plugins can be used for HTTP requests. The example above shows two functions, such as pre_request (That will happen before the controller) and post_request (That will happen after the controller).

Prioritization & Configuration

We want to say in what order we want plugins to be run. We do this in sys.config where we also can set extra options for the plugins.

{nova, [
         {use_stacktrace, true},
         {environment, dev},
         {cowboy_configuration, #{
                                  port => 8080
                                 }},
         {dev_mode, true},
         {bootstrap_application, my_first_nova}, %% Bootstraps the application
         %% Plugins is written on form {RequestType, Module, Options, Priority}
         %% Priority is that the lowest number is executed first
         {plugins, [
                    {pre_request, nova_request_plugin, #{decode_json_body => true}}
                   ]}
        ]}
  %% Please change your app.src-file instead if you intend to add app-specific configurations
Enter fullscreen mode Exit fullscreen mode

In this scenario:
nova_request_plugin is a plugin that is included with Nova, it can handle some decoding of incomming bodies.

To read more about what plugins are included in Nova you can read it here.

What we want to do in our application is that we are later going to create a view that will send in an urlencoded body from a form submit. An easy login page.

If we want Nova to decode this urlencoded body we will need to change our plugin setting to:

    {plugins, [
            {pre_request, nova_request_plugin, #{read_urlencoded_body => true}}
            ]}
Enter fullscreen mode Exit fullscreen mode

Heroku

Simplify your DevOps and maximize your time.

Since 2007, Heroku has been the go-to platform for developers as it monitors uptime, performance, and infrastructure concerns, allowing you to focus on writing code.

Learn More

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay