A simple, standardized interface library to Erlang HTTP Servers.
Erlang
113
554 commits
updated Jul 27, 2026
SimpleBridge takes the pain out of coding to multiple Erlang HTTP servers by creating a standardized interface. It currently supports Cowboy, Inets, Mochiweb, Webmachine, and Yaws.
SimpleBridge is used as the bridge to webservers for two of the most popular Erlang web frameworks: Nitrogen Web Framework and ChicagoBoss
In a sense, it is similar to EWGI, except SimpleBridge has some key improvements/differences:
Easily extended - Takes between 200 and 400 lines to add support for a new HTTP server, including the Bridge module itself, as well as default supervisor, and anchor module.
Websockets - SimpleBridge provides a single interface for handling websockets. Even servers which don't natively support websockets have a websocket layer with SimpleBridge. This means you can run websockets on Inets, Mochiweb, and Webmachine, none of which natively support Websockets.
MultiPart File Uploads - SimpleBridge has better support for HTTP POSTS, including support for multipart file uploads, with size limits and handle-able errors.
Static File Support - Support for sending a static file to the browser, using the underlying HTTP server's own methods.
Cookies Support - SimpleBridge provides interface functions for getting and setting cookies.
No Middleware Components - SimpleBridge does not explicitly support EWGI's concept of "middleware components". (Though you could probably fake it, haven't tried.)
SimpleBridge is split into three parts:
% SimpleBridge Hello World Example
start() ->
Handler = ?MODULE,
simple_bridge:start(mochiweb, Handler).
run(Bridge) ->
HTML = [
"<h1>Hello, World!</h1>",
io_lib:format("METHOD: ~p~n<br><br>", [sbw:request_method(Bridge)]),
io_lib:format("COOKIES: ~p~n<br><br>", [sbw:cookies(Bridge)]),
io_lib:format("HEADERS: ~p~n<br><br>", [sbw:headers(Bridge)]),
io_lib:format("QUERY PARAMETERS: ~p~n<br><br>", [sbw:query_params(Bridge)])
],
Bridge2 = sbw:set_status_code(200, Bridge),
Bridge3 = sbw:set_header("Content-Type", "text/html", Bridge2),
Bridge4 = sbw:set_response_data(HTML, Bridge3),
sbw:build_response(Bridge4).
To see a complete example handler page using SimpleBridge, demonstrating the results of requests, as well as providing a simple echo websocket server, look at the code of simple_bridge_handler_sample.
There is a built-in quickstart for demoing simple bridge with any backend, using the example mentioned above.
To try it out:
git clone -b ws git://github.com/nitrogen/simple_bridge.git
cd simple_bridge
make run_inets
# Feel free to replace "inets" with "cowboy", "mochiweb", "webmachine", or "yaws"
Then, open your browser and navigate to http://127.0.0.1:8000
As demonstrated above, the simplest approach is to just start simple bridge with the appropriate backend (or use the simple_bridge.config). Simple Bridge will then start the server to the specs of your choice.
The following are all valid ways to start Simple Bridge:
%% Explicitly start with particular Backend and HandlerMod
simple_bridge:start(Backend, HandlerMod).
%% HandlerMod is determined from the handler config variable
simple_bridge:start(Backend).
%% Backend and HandlerMod are both determined by the configuration
simple_bridge:start().
%% Same as simple_bridge:start().
application:start(simple_bridge).
Note: You will still need to ensure that the dependencies are there for the webserver of your choice. For example, trying to start Yaws without the yaws application currently in your dependencies will fail.
When creating your server using any of the above methods, simple_bridge will automatically use the backend-specific anchor module for the chosen backend provided by Simple Bridge.
The anchor module serves as an additional layer to eliminate the need to write any platform-specific code in your application. The anchor module will transform the platform-specific requests and pass them off to the Handler Module in a uniform fashion.
A Handler module is a standard module that SimpleBridge will call out to when a request is made, both standard HTTP requests, and websocket frames.
A Handler module is expected to export the following functions:
run(Bridge) - Bridge will be an initialized instance of a SimpleBridge
object, and the last step of the run will be the return value of
sbw:build_response(Bridge)ws_init(Bridge) - Called when a websocket connection is initialized.
ok - Everything went okay, proceed with the connection.{ok, State} - Everything went okay, proceeed with connection and
initialize with the provided State (which will be passed to
ws_message, ws_info, and ws_terminate functions.close - Everything did not go okay, let's shut down the connection.ws_message(Message, Bridge, State) - Called when a websocket client has
sent us something.
Message can be:
{Type, Data} - Type will be either binary or text, depending on
the nature of the message. Data will always be a binary. By the nature of the
WebSocket protocol, you can be guaranteed that if Type==text, that Data
will be verified to be valid UTF8 Unicode.noreply - No reply will be made.{noreply, NewState} - No reply will be made, but change the state to
NewState{reply, {Type, Data}} - Type can be text or binary and Data
can be a binary, list, or iolist.{reply, {Type, Data}, NewState} - Same as {reply, {Type, Data}},
except that the internal state will be changed to NewState{reply, [{Type, Data}]} - Reply with a list of {Type, Data} pairs
as a single message broken into several frames.{reply, [{Type, Data}], NewState} - Same as {reply, [{Type, Data}]}
except change the state to NewStateclose - Kill the connection (will provide the Websocket Error code 1000){close, StatusCode} - Kill the connection with StatusCode (See
RFC6455 Sec 7.4.1
for the list of valid connection codes).ws_info(Message, Bridge, State) - Called when the websocket process receives a
message (that is, a message was sent from an Erlang process).
Message can be any termws_messagews_terminate(ReasonCode, Bridge, State) - The websocket is shutting down with
ReasonCode.
okNotice that each of the call above passes in a Bridge object. This object
will be how you interface with the underlying server, both retrieving
information about the request (headers, query strings, etc), as well as
building your response to the server.
State and WebsocketsIn the above handler functions, State can be any term. It's for your own
applications to track the state of your application's. The State is local
only to the specific client's connection. For example, it could be used for
storing a session identifier (for quick lookup in the session key-value store,
rather than having to read a cookie from the Bridge object), or for tracking
some user-specific value that might change from message to message, such as
"Away" or "Do Not Disturb" status. It's provided as a convenience so that you
won't need to rely on the process dictionary for tracking this state. As soon
as the connection dies, this State will cease to exist. It is not, as one
might be inclined to believe, an application-wide state.
If your function returns, for example, the atom noreply or the {reply, Message} two-tuples, then State will remain unchanged. As such, if you
simply don't care about using the State variable, then you could easily
ignore the State variable by matching it with _ in your function
definitions, and retuning the "Stateless" versions of each return value
(noreply, {reply, Message}).
Once you have created Bridge object, you can interface with it using a series of standardized function calls universal to all bridges.
You can interface with it using the sbw module "sbw" is an acronym for
(S)imple (B)ridge (W)rapper.
NOTE: Tuple Module style calls were officially disabled in Erlang 21 and require you to enable tuple calls as a compile option in your module with:
-compile(tuple_calls).
This option can also be specified in your rebar.config file in the erl_opts
variable with:
{erl_opts, [tuple_calls]}.
Simple Bridge is no longer tested with tuple-module calls as of Simple Bridge 2.2.0
Backwards Compatibility Note: Simple Bridge 1.x required a separate Request and Response Object. This has gone away and now a single Bridge "object" provides both the Request and Response interface in a single object. This means you no longer have to track both a request and a response bridge in your application. A single bridge will do, pig.
x-forwarded-for header.{74, 125, 67, 100}).{<<"header">>, <<"Value1">>}, {<<"header2">>, <<"Value2">>}, ...].[{<<"cookie1">>, <<"Value1">>}, {<<"cookie2">>, <<"Value2">>}, ...].[{<<"Query1">>, <<"Value1">>}, {<<"Query2">>, <<"Value2">>}, ...].Param, undefined if not found.Param as list, ["Value1", "Value2", ...], [] if none
found.[{"Post1", "Value1"}, {"Post2", "Value2"}, ...].Param, undefined if not foundParam as list, ["Value1", "Value2", ...], [] if none
found.Param, undefined if not found["Value1", "Value2", ...], [] if none
found.#sb_uploaded_file records,
describing the files uploaded in a multipart post. These can be
conveniently interfaced with the sb_uploaded_file module, documented below
in the "Uploaded File Interface" section.(+) Return Values will be a proplist of binaries. Keys are normalized to lower-case binaries.
(++) Return type will be dependent on the provided Key (Cookie, Header,
Param, etc). If the Key is a binary, the return type will be binary. If Key
is an atom or a string (list), the return type will be a string.
sbw:post_files(Bridge) returns a list of #sb_uploaded_file records, but it's
inconvenient to have to include the simple_bridge.hrl header in your
application's modules. The safer and more portable approach is to use the
sb_uploaded_file module provided by Simple Bridge.
As with the Bridge module above, all sb_uploaded_file objects can be referenced by:
sb_uploaded_file:function_name(File)sb_uploaded_file exports the following functions:
undefined if file is kept in memory.<input type=file>
element from the page.undefined
if file is stored as temporary file on disk.By default uploaded files are always stored in temporary file
sb_uploaded_file:temp_file(UploadedFile). If you want to keep the uploaded
files in memory (sb_uploaded_file:data(UploadedFile)) instead of on disk, set
the max memory size for uploaded files by setting the simple_bridge
configuration variable {max_file_in_memory_size, SizeinMB}. Uploaded files
larger than SizeInMB are still stored in temporary files.
The response portion of the Bridge object provides you with a standard interface for adding response status codes, headers, cookies, and a body.
Each function below returns a new bridge object, so you will need to chain together requests like this:
run(Bridge) ->
Bridge1 = sbw:set_status_code(200, Bridge),
Bridge2 = sbw:set_header("Header1", "Value1", Bridge1),
Bridge3 = sbw:set_response_data(HTML, Bridge2),
sbw:build_response(Bridge3).
The Bridge modules export the following functions:
domain, path, max_age, secure, same_site and http_only.
Any or all can be specified like below. Options = [
{domain, undefined},
{path, "/"},
{max_age, 3600}, %% time in seconds
{secure, false},
{http_only, false},
{same_site, none} %% can be: none | strict | lax
],
sbw:set_cookie("mycookie", "mycookievalue", Options, Bridge).
Path with MinutesToLive to
define the max age of the cookie. Deprecated in favor of sbw:set_cookie/4.Finally, you build the response to send to your HTTP server with the
sbw:build_response/1 function.
DEPRECATION NOTICE: For backwards compatibility with SimpleBridge Version 1, the following functions are also exported. Please refrain from using them in future code, as they are deprecated.
sbw:set_status_code/2.sbw:set_header/3sbw:set_cookie/3/5sbw:set_response_data/2sbw:set_response_file/2The configuration optiosn found in etc/simple_bridge.config are all full
documented within the config file itself. Feel free to copy it to your project
and use it as a base.
Simple Bridge 2.0 should be mostly compatible with 1.x versions mostly right out of the box, but is only compatible through deprecations.
The recommended approach to migrating to 2.x is to remove instantiating your
Bridge altogether (that is, remove your simple_bridge:make_request and
simple_bridge:make_response functions from your app, and instead rely on the
"Handler" module (above) for handling requests, and the simple_bridge.config
file for setting up the backend server.
When doing this, instead of starting the backend servers yourself in the code,
you can rely on Simple Bridge to correctly set up the right configuration based
on simple_bridge.config and instantiate the server in the correct way, and
then starting your server with Simple Bridge by using something like
simple_bridge:start(yaws, my_handler_module) (or check the "Starting Simple
Bridge" section above).
Following this paradigm, however, is not a requirement. If you want to maintain the same basic structure of your app, starting the server yourself, handling the requests yourself, and then simply using Simple Bridge to interface with the requests and response, then the recommended approach would be to convert calls like:
ReqBridge = simple_bridge:make_request(cowboy_request_module, Req),
ResBridge = simple_bridge:make_response(cowboy_response_module, Req),
...
ResBridge:build_response().
to simply using:
Bridge = simple_bridge:make(cowboy, Req),
...
sbw:build_response(Bridge).
One of the other things to look out for with the move to 2.0 is the handling of query parameter, post parameters, and headers.
sbw:headers/1, sbw:query_params/1, and
sbw:post_params/1 functions is now a list of proplists of binaries.sbw:header/query_param/post_param/etc
functions however, will be based on the key provided. For example, calling
sbw:header("x-forwarded-for", Bridge) will return a list, while
sbw:header(<<"x-forwarded-for">>, Bridge) will return a binary.The last thing to deal with when converting from 1.x to 2.0 is making the
changes from the old-style response bridge calls to the new names for the same
functions. This change was made to disambiguate some of the confusion that
would arise from having sbw:header/2,3,4 and sbw:cookie/2,3,5 some of which
being setters and some being getters.
So Make sure that you're using sbw:set_status_code instead of
Bridge:status_code, sbw:set_header instead of Bridge:header, etc. The
thing to note, is that all of the non-deprecated response functions begin
with a verb (e.g. set_response_data, clear_cookies, build_response,
etc). See the "DEPRECATION NOTICE" a few sections above.
We can be found on:
#nitrogenIf you wish to contribute to SimpleBridge's development, check out our contribution guidelines.
Simple Bridge was created by Rusty Klophaus in 2008 and has been maintained by Jesse Gumm since 2011.
Simple Bridge is copyright 2008-2023 Rusty Klophaus and Jesse Gumm.
Licensed under the MIT License
Erlang
97.5%
Makefile
1.5%
JavaScript
1.1%
A simple, standardized interface library to Erlang HTTP Servers.
Erlang
113
554 commits
updated Jul 27, 2026
SimpleBridge takes the pain out of coding to multiple Erlang HTTP servers by creating a standardized interface. It currently supports Cowboy, Inets, Mochiweb, Webmachine, and Yaws.
SimpleBridge is used as the bridge to webservers for two of the most popular Erlang web frameworks: Nitrogen Web Framework and ChicagoBoss
In a sense, it is similar to EWGI, except SimpleBridge has some key improvements/differences:
Easily extended - Takes between 200 and 400 lines to add support for a new HTTP server, including the Bridge module itself, as well as default supervisor, and anchor module.
Websockets - SimpleBridge provides a single interface for handling websockets. Even servers which don't natively support websockets have a websocket layer with SimpleBridge. This means you can run websockets on Inets, Mochiweb, and Webmachine, none of which natively support Websockets.
MultiPart File Uploads - SimpleBridge has better support for HTTP POSTS, including support for multipart file uploads, with size limits and handle-able errors.
Static File Support - Support for sending a static file to the browser, using the underlying HTTP server's own methods.
Cookies Support - SimpleBridge provides interface functions for getting and setting cookies.
No Middleware Components - SimpleBridge does not explicitly support EWGI's concept of "middleware components". (Though you could probably fake it, haven't tried.)
SimpleBridge is split into three parts:
% SimpleBridge Hello World Example
start() ->
Handler = ?MODULE,
simple_bridge:start(mochiweb, Handler).
run(Bridge) ->
HTML = [
"<h1>Hello, World!</h1>",
io_lib:format("METHOD: ~p~n<br><br>", [sbw:request_method(Bridge)]),
io_lib:format("COOKIES: ~p~n<br><br>", [sbw:cookies(Bridge)]),
io_lib:format("HEADERS: ~p~n<br><br>", [sbw:headers(Bridge)]),
io_lib:format("QUERY PARAMETERS: ~p~n<br><br>", [sbw:query_params(Bridge)])
],
Bridge2 = sbw:set_status_code(200, Bridge),
Bridge3 = sbw:set_header("Content-Type", "text/html", Bridge2),
Bridge4 = sbw:set_response_data(HTML, Bridge3),
sbw:build_response(Bridge4).
To see a complete example handler page using SimpleBridge, demonstrating the results of requests, as well as providing a simple echo websocket server, look at the code of simple_bridge_handler_sample.
There is a built-in quickstart for demoing simple bridge with any backend, using the example mentioned above.
To try it out:
git clone -b ws git://github.com/nitrogen/simple_bridge.git
cd simple_bridge
make run_inets
# Feel free to replace "inets" with "cowboy", "mochiweb", "webmachine", or "yaws"
Then, open your browser and navigate to http://127.0.0.1:8000
As demonstrated above, the simplest approach is to just start simple bridge with the appropriate backend (or use the simple_bridge.config). Simple Bridge will then start the server to the specs of your choice.
The following are all valid ways to start Simple Bridge:
%% Explicitly start with particular Backend and HandlerMod
simple_bridge:start(Backend, HandlerMod).
%% HandlerMod is determined from the handler config variable
simple_bridge:start(Backend).
%% Backend and HandlerMod are both determined by the configuration
simple_bridge:start().
%% Same as simple_bridge:start().
application:start(simple_bridge).
Note: You will still need to ensure that the dependencies are there for the webserver of your choice. For example, trying to start Yaws without the yaws application currently in your dependencies will fail.
When creating your server using any of the above methods, simple_bridge will automatically use the backend-specific anchor module for the chosen backend provided by Simple Bridge.
The anchor module serves as an additional layer to eliminate the need to write any platform-specific code in your application. The anchor module will transform the platform-specific requests and pass them off to the Handler Module in a uniform fashion.
A Handler module is a standard module that SimpleBridge will call out to when a request is made, both standard HTTP requests, and websocket frames.
A Handler module is expected to export the following functions:
run(Bridge) - Bridge will be an initialized instance of a SimpleBridge
object, and the last step of the run will be the return value of
sbw:build_response(Bridge)ws_init(Bridge) - Called when a websocket connection is initialized.
ok - Everything went okay, proceed with the connection.{ok, State} - Everything went okay, proceeed with connection and
initialize with the provided State (which will be passed to
ws_message, ws_info, and ws_terminate functions.close - Everything did not go okay, let's shut down the connection.ws_message(Message, Bridge, State) - Called when a websocket client has
sent us something.
Message can be:
{Type, Data} - Type will be either binary or text, depending on
the nature of the message. Data will always be a binary. By the nature of the
WebSocket protocol, you can be guaranteed that if Type==text, that Data
will be verified to be valid UTF8 Unicode.noreply - No reply will be made.{noreply, NewState} - No reply will be made, but change the state to
NewState{reply, {Type, Data}} - Type can be text or binary and Data
can be a binary, list, or iolist.{reply, {Type, Data}, NewState} - Same as {reply, {Type, Data}},
except that the internal state will be changed to NewState{reply, [{Type, Data}]} - Reply with a list of {Type, Data} pairs
as a single message broken into several frames.{reply, [{Type, Data}], NewState} - Same as {reply, [{Type, Data}]}
except change the state to NewStateclose - Kill the connection (will provide the Websocket Error code 1000){close, StatusCode} - Kill the connection with StatusCode (See
RFC6455 Sec 7.4.1
for the list of valid connection codes).ws_info(Message, Bridge, State) - Called when the websocket process receives a
message (that is, a message was sent from an Erlang process).
Message can be any termws_messagews_terminate(ReasonCode, Bridge, State) - The websocket is shutting down with
ReasonCode.
okNotice that each of the call above passes in a Bridge object. This object
will be how you interface with the underlying server, both retrieving
information about the request (headers, query strings, etc), as well as
building your response to the server.
State and WebsocketsIn the above handler functions, State can be any term. It's for your own
applications to track the state of your application's. The State is local
only to the specific client's connection. For example, it could be used for
storing a session identifier (for quick lookup in the session key-value store,
rather than having to read a cookie from the Bridge object), or for tracking
some user-specific value that might change from message to message, such as
"Away" or "Do Not Disturb" status. It's provided as a convenience so that you
won't need to rely on the process dictionary for tracking this state. As soon
as the connection dies, this State will cease to exist. It is not, as one
might be inclined to believe, an application-wide state.
If your function returns, for example, the atom noreply or the {reply, Message} two-tuples, then State will remain unchanged. As such, if you
simply don't care about using the State variable, then you could easily
ignore the State variable by matching it with _ in your function
definitions, and retuning the "Stateless" versions of each return value
(noreply, {reply, Message}).
Once you have created Bridge object, you can interface with it using a series of standardized function calls universal to all bridges.
You can interface with it using the sbw module "sbw" is an acronym for
(S)imple (B)ridge (W)rapper.
NOTE: Tuple Module style calls were officially disabled in Erlang 21 and require you to enable tuple calls as a compile option in your module with:
-compile(tuple_calls).
This option can also be specified in your rebar.config file in the erl_opts
variable with:
{erl_opts, [tuple_calls]}.
Simple Bridge is no longer tested with tuple-module calls as of Simple Bridge 2.2.0
Backwards Compatibility Note: Simple Bridge 1.x required a separate Request and Response Object. This has gone away and now a single Bridge "object" provides both the Request and Response interface in a single object. This means you no longer have to track both a request and a response bridge in your application. A single bridge will do, pig.
x-forwarded-for header.{74, 125, 67, 100}).{<<"header">>, <<"Value1">>}, {<<"header2">>, <<"Value2">>}, ...].[{<<"cookie1">>, <<"Value1">>}, {<<"cookie2">>, <<"Value2">>}, ...].[{<<"Query1">>, <<"Value1">>}, {<<"Query2">>, <<"Value2">>}, ...].Param, undefined if not found.Param as list, ["Value1", "Value2", ...], [] if none
found.[{"Post1", "Value1"}, {"Post2", "Value2"}, ...].Param, undefined if not foundParam as list, ["Value1", "Value2", ...], [] if none
found.Param, undefined if not found["Value1", "Value2", ...], [] if none
found.#sb_uploaded_file records,
describing the files uploaded in a multipart post. These can be
conveniently interfaced with the sb_uploaded_file module, documented below
in the "Uploaded File Interface" section.(+) Return Values will be a proplist of binaries. Keys are normalized to lower-case binaries.
(++) Return type will be dependent on the provided Key (Cookie, Header,
Param, etc). If the Key is a binary, the return type will be binary. If Key
is an atom or a string (list), the return type will be a string.
sbw:post_files(Bridge) returns a list of #sb_uploaded_file records, but it's
inconvenient to have to include the simple_bridge.hrl header in your
application's modules. The safer and more portable approach is to use the
sb_uploaded_file module provided by Simple Bridge.
As with the Bridge module above, all sb_uploaded_file objects can be referenced by:
sb_uploaded_file:function_name(File)sb_uploaded_file exports the following functions:
undefined if file is kept in memory.<input type=file>
element from the page.undefined
if file is stored as temporary file on disk.By default uploaded files are always stored in temporary file
sb_uploaded_file:temp_file(UploadedFile). If you want to keep the uploaded
files in memory (sb_uploaded_file:data(UploadedFile)) instead of on disk, set
the max memory size for uploaded files by setting the simple_bridge
configuration variable {max_file_in_memory_size, SizeinMB}. Uploaded files
larger than SizeInMB are still stored in temporary files.
The response portion of the Bridge object provides you with a standard interface for adding response status codes, headers, cookies, and a body.
Each function below returns a new bridge object, so you will need to chain together requests like this:
run(Bridge) ->
Bridge1 = sbw:set_status_code(200, Bridge),
Bridge2 = sbw:set_header("Header1", "Value1", Bridge1),
Bridge3 = sbw:set_response_data(HTML, Bridge2),
sbw:build_response(Bridge3).
The Bridge modules export the following functions:
domain, path, max_age, secure, same_site and http_only.
Any or all can be specified like below. Options = [
{domain, undefined},
{path, "/"},
{max_age, 3600}, %% time in seconds
{secure, false},
{http_only, false},
{same_site, none} %% can be: none | strict | lax
],
sbw:set_cookie("mycookie", "mycookievalue", Options, Bridge).
Path with MinutesToLive to
define the max age of the cookie. Deprecated in favor of sbw:set_cookie/4.Finally, you build the response to send to your HTTP server with the
sbw:build_response/1 function.
DEPRECATION NOTICE: For backwards compatibility with SimpleBridge Version 1, the following functions are also exported. Please refrain from using them in future code, as they are deprecated.
sbw:set_status_code/2.sbw:set_header/3sbw:set_cookie/3/5sbw:set_response_data/2sbw:set_response_file/2The configuration optiosn found in etc/simple_bridge.config are all full
documented within the config file itself. Feel free to copy it to your project
and use it as a base.
Simple Bridge 2.0 should be mostly compatible with 1.x versions mostly right out of the box, but is only compatible through deprecations.
The recommended approach to migrating to 2.x is to remove instantiating your
Bridge altogether (that is, remove your simple_bridge:make_request and
simple_bridge:make_response functions from your app, and instead rely on the
"Handler" module (above) for handling requests, and the simple_bridge.config
file for setting up the backend server.
When doing this, instead of starting the backend servers yourself in the code,
you can rely on Simple Bridge to correctly set up the right configuration based
on simple_bridge.config and instantiate the server in the correct way, and
then starting your server with Simple Bridge by using something like
simple_bridge:start(yaws, my_handler_module) (or check the "Starting Simple
Bridge" section above).
Following this paradigm, however, is not a requirement. If you want to maintain the same basic structure of your app, starting the server yourself, handling the requests yourself, and then simply using Simple Bridge to interface with the requests and response, then the recommended approach would be to convert calls like:
ReqBridge = simple_bridge:make_request(cowboy_request_module, Req),
ResBridge = simple_bridge:make_response(cowboy_response_module, Req),
...
ResBridge:build_response().
to simply using:
Bridge = simple_bridge:make(cowboy, Req),
...
sbw:build_response(Bridge).
One of the other things to look out for with the move to 2.0 is the handling of query parameter, post parameters, and headers.
sbw:headers/1, sbw:query_params/1, and
sbw:post_params/1 functions is now a list of proplists of binaries.sbw:header/query_param/post_param/etc
functions however, will be based on the key provided. For example, calling
sbw:header("x-forwarded-for", Bridge) will return a list, while
sbw:header(<<"x-forwarded-for">>, Bridge) will return a binary.The last thing to deal with when converting from 1.x to 2.0 is making the
changes from the old-style response bridge calls to the new names for the same
functions. This change was made to disambiguate some of the confusion that
would arise from having sbw:header/2,3,4 and sbw:cookie/2,3,5 some of which
being setters and some being getters.
So Make sure that you're using sbw:set_status_code instead of
Bridge:status_code, sbw:set_header instead of Bridge:header, etc. The
thing to note, is that all of the non-deprecated response functions begin
with a verb (e.g. set_response_data, clear_cookies, build_response,
etc). See the "DEPRECATION NOTICE" a few sections above.
We can be found on:
#nitrogenIf you wish to contribute to SimpleBridge's development, check out our contribution guidelines.
Simple Bridge was created by Rusty Klophaus in 2008 and has been maintained by Jesse Gumm since 2011.
Simple Bridge is copyright 2008-2023 Rusty Klophaus and Jesse Gumm.
Licensed under the MIT License
Erlang
97.5%
Makefile
1.5%
JavaScript
1.1%