Skip to content

Commit

Permalink
Added plugin documentation (#248)
Browse files Browse the repository at this point in the history
  • Loading branch information
Taure authored Dec 27, 2023
1 parent aa4c890 commit cd7205c
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 10 deletions.
7 changes: 1 addition & 6 deletions guides/plugins_and_handlers.md → guides/handlers.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,8 @@
# Plugins and handlers
# Handlers

## Handlers

Handlers are a nifty thing that is called on when the controller returns. For example if the controller returns
`{json, #{hello => world}}` we would like Nova to create a proper JSON response to the requester. That means setting correct
headers, encode the payload and send it out. This is what _handlers_ are for. They are (often short) functions that transforms something like
`{json, Payload}` to proper output.

## Plugins

Plugins are a bit like the handlers except they are run on request. There's currently two different type of plugins; `pre_request` and `post_request`.
These can be used to create access logs, insert CORS headers or similar.
2 changes: 1 addition & 1 deletion guides/nova-pubsub.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Nova Pubsub

With version 0.9.4 we introduced the concept of a pubsub-like mechanism in Nova so that users can build distributed services. Internally it relies on Erlangs `pg2`-module which enables distributed named process groups. The concept is really simple and there's not much depth in the current implementation - it should only be used as a simple message bus. If you need more advanced features please take a look at [RabbitMQ](rabbitmq) or [MQTT](https://mqtt.org).
With version 0.9.4 we introduced the concept of a pubsub-like mechanism in Nova so that users can build distributed services. Internally it relies on Erlangs `pg2`-module which enables distributed named process groups. The concept is really simple and there's not much depth in the current implementation - it should only be used as a simple message bus. If you need more advanced features please take a look at [RabbitMQ](https://www.rabbitmq.com/) or [MQTT](https://mqtt.org).

## Basic concepts

Expand Down
54 changes: 54 additions & 0 deletions guides/plugins.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Plugins

Plugins are a bit like the handlers except they are run on request. There's currently two different type of plugins; `pre_request` and `post_request`.
These can be used to create access logs, insert CORS headers or similar.

Plugins are used to handle things before and/or after a request. They are applied on all requests of a specified protocol.

This is an example:
Expand Down Expand Up @@ -67,3 +70,54 @@ increment(#{<<"json">> := #{<<"id">> := Id, <<"value">> := Value}})->
{json,200,#{},#{<<"id">> => Id , <<"received">> => Value, <<"increment">> => Value+1}}.
```
## Nova plugins

Nova has a couple of plugins for some general purposes.

|Plugin|Description|Code|
|nova_correlation_plugin|This plugin will add a correlation id to header response but also add `#{correlation_id => CorrelationID}` to the request obj that is passed to the controller.|[nova_correlation_plugin](https://github.com/novaframework/nova/blob/master/src/plugins/nova_correlation_plugin.erl)|
|nova_cors_plugin|This plugin will handle cors and add the cors headers into the request.|[nova_cors_plugin](https://github.com/novaframework/nova/blob/master/src/plugins/nova_cors_plugin.erl)|
|nova_request_plugin|This plugin will handle incomming data like qs, form urlencoded and json|[nova_request_plugin](https://github.com/novaframework/nova/blob/master/src/plugins/nova_request_plugin.erl)|


### Nova correlation

This plugin will generate a uuid v4 and set it as a response header as `X-Correlation-ID` if nothing is configuered.

```erlang
{pre_request; nova_correlation_plugin, #{request_correlation_header => CorrelationHeader,
logger_metadata_key => LoggerMetaDataKey}}
```

|Option|Description|
|request_correlation_header|This is if you want a different correlation header than the standard `X-Correlation-ID`|
|logger_metadata_key| This is if you want to have a different metadata key then the standard `correaltion_id`|

### Nova cors

This plugins will make it so that if we get method OPTIONS it will just return back the CORS headers. In this case you don't need a controller to handle it and the plugin stops after this.
For other methods it will add the CORS headers to the request.

```erlang
{pre_request; nova_cors_plugin, #{allow_origins => <<"*">>}}
```

|Option|Description|
|allow_origins|Specifies which origins to insert into Access-Control-Allow-Origin|

### Nova request

This plugins handle incoming data and can transform them to erlang maps depending on what the options are.

```erlang
{pre_request; nova_correlation_plugin, #{decode_json_body => true,
read_urlencoded_body => true,
parse_qs => true|list}}
```


|Option|Description|Req|
|decode_json_body|If header is application/json it will decode the body.| `Req#{json => Map}`|
|read_urlencoded_body|If header is application/x-www-form-urlencoded it will decode it.| `Req#{params => Map}`|
|parse_qs| If the path have qs in it we will get them.|`Req#{parsed_qs => Map or List}`|

4 changes: 2 additions & 2 deletions rebar.config
Original file line number Diff line number Diff line change
Expand Up @@ -117,10 +117,10 @@
<<"guides/routing.md">>,
<<"guides/controllers.md">>,
<<"guides/views.md">>,
<<"guides/plugins_and_handlers.md">>,
<<"guides/handlers.md">>,
<<"guides/plugins.md">>,
<<"guides/building-releases.md">>,
<<"guides/books-and-links.md">>,
<<"guides/plugins.md">>,
<<"guides/rebar3_nova.md">>,
<<"guides/nova-pubsub.md">>]},
{source_url, <<"https://github.com/novaframework/nova">>}
Expand Down
2 changes: 1 addition & 1 deletion src/nova_watcher.erl
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ handle_cast(_Request, State) ->
{noreply, NewState :: term(), Timeout :: timeout()} |
{noreply, NewState :: term(), hibernate} |
{stop, Reason :: normal | term(), NewState :: term()}.
handle_info({ProcessRef, {data, Data}}, State) ->
handle_info({_ProcessRef, {data, Data}}, State) ->
Msg = case Data of
{eol, Text} -> Text;
_ -> Data
Expand Down

0 comments on commit cd7205c

Please sign in to comment.