Getting Started
Welcome to Ace; Once added to your project this guide will demonstrate setting up a simple end point.
Stream handlers
The first step is define a stream handler for you application. Using the Raxx adapter is the simplest way to get started.
defmodule MyApp.SimpleHandler do
use Ace.HTTP2.Stream.RaxxHandler
def handle_request(_request, _config) do
Raxx.Response.ok("Hello, World!", [{"content-length", "13"}])
end
end
A stream handler and configuration are used to start a worker for every stream.
Note
The Raxx handler is provided when simple request -> response usecases. Defining a custom handler can support streaming up or down (or both).
TLS(SSL) credentials
Ace only supports using a secure transport layer. Therefore a certificate and certificate_key are needed to server content.
For local development a self signed certificate can be used.
Note
Store certificates in a projects priv
directory if they are to be distributed as part of a release.
Endpoint setup
defmodule MyApp.Application do
@moduledoc false
use Application
def start(_type, _args) do
certfile = Application.app_dir(:my_app, "/priv/cert.pem")
keyfile = Application.app_dir(:my_app, "/priv/key.pem")
Ace.HTTP2.start_link(
{MyApp.SimpleHandler, :config},
8443,
certfile: certfile,
keyfile: keyfile,
connections: 1_000
)
end
end
Note
Ace.HTTP2.start_link/3
Can be used to add one or more HTTP2 endpoint to an application supervision tree.
Bidirectional streaming
Process will receive data messages in the following format untill all data is sent from client
1
{stream, %{headers: list(), end_stream: boolean()}}
0 - n
{stream, %{data: binary(), end_stream: boolean()}}
The worker can stream data to the client at any point using
StreamHandler.send_to_client(stream, %{headers: headers(), end_stream: boolean()})
# OR
StreamHandler.send_to_client(stream, %{data: binary(), end_stream: boolean()})
Example
defmodule MyApp.StreamHandler do
use GenServer
alias Ace.HTTP2.StreamHandler
def start_link(config) do
GenServer.start_link(__MODULE__, config)
end
def handle_info({stream, {:headers, _}}, state) do
response_headers = %{
headers: [{":status", "200"}, {"content-length", "13"}],
end_stream: false
}
StreamHandler.send_to_client(stream, response_headers)
response_body = %{
data: "Hello, World!",
end_stream: true
}
StreamHandler.send_to_client(stream, response_body)
{:stop, :normal, state}
end
end