View Source CozyProxy (cozy_proxy v0.2.1)

Proxy requests to other plugs.

usage

Usage

CozyProxy instances are isolated supervision trees and you can include it in application's supervisor:

# lib/demo/application.ex
def start(_type, _args) do
  children = [
    # ...
    {CozyProxy, Application.fetch_env!(:demo, CozyProxy)}
  ]

  opts = [strategy: :one_for_one, name: Demo.Supervisor]
  Supervisor.start_link(children, opts)
end

Above code requires a piece of configuration:

config :demo, CozyProxy,
  http: [port: 8080],
  backends: [
    %{
      plug: HealthCheckPlug,
      path: "/health-check"
    },
    %{
      plug: DemoWebAPI.Endpoint,
      path: "/api"
    },
    %{
      plug: DemoAdminWeb.Endpoint,
      path: "/admin"
    },
    %{
      plug: DemoWeb.Endpoint,
      path: "/"
    }
  ]

When using CozyProxy, it's better to configure Phoenix endpoints to not start servers, in order to avoid Phoenix endpoints bypassing CozyProxy:

config :demo, DemoWeb.Endpoint, server: false
config :demo, DemoWebAPI.Endpoint, server: false
config :demo, DemoAdminWeb.Endpoint, server: false

configurations

Configurations

  • :http - the configuration for the HTTP server. It accepts all options as defined by Plug.Cowboy.
  • :https - the configuration for the HTTPS server. It accepts all options as defined by Plug.Cowboy.
  • :server - false by default. It can be aware of Phoenix startup arguments, if you are running the application with mix phx.server or iex -S mix phx.server, this option will be always considered as true.
  • :backends - the configuration of backends. See next section for more details.

about-backends

about :backends

A valid configuration of :backends is a list of maps, and the keys of maps are:

  • :plug:
    • required
    • typespec: module() | {module(), keyword()}

    • examples:
      • HealthCheckPlug
      • {HealthCheckPlug, []}
      • ...
  • :method:
    • optional
    • typespec: String.t()
    • examples:
      • "GET"
      • "POST"
      • ...
  • :host:
    • optional
    • typespec: String.t()
    • examples:
      • "example.com"
      • ...
  • :path:
    • optional
    • typespec: String.t()
    • examples:
      • "/admin"
      • "/api"
      • ...

notes

Notes

rewritting-path

Rewritting path

If there's a backend like this:

%Backend{
  plug: ...,
  method: nil,
  host: nil,
  path: "/api"
}

When the backend is matched, the request path like /api/v1/users will be rewritten as /v1/users.

the-order-of-backends-matters

The order of backends matters

If you configure the backends like this:

config :demo, CozyProxy,
  backends: [
    %{
      plug: DemoUserWeb.Endpoint,
      path: "/"
    },
    %{
      plug: DemoUserAPI.Endpoint,
      path: "/api"
    },
    %{
      plug: DemoAdminWeb.Endpoint,
      path: "/admin"
    },
    %{
      plug: HealthCheck,
      path: "/health-check"
    }
  ]

The first backend will always match, which may not what you expected.

If you want all backends to have a chance to match, you should configure them like this:

config :demo, CozyProxy,
  backends: [
    %{
      plug: HealthCheck,
      path: "/health-check"
    },
    %{
      plug: DemoUserAPI.Endpoint,
      path: "/api"
    },
    %{
      plug: DemoAdminWeb.Endpoint,
      path: "/admin"
    },
    %{
      plug: DemoUserWeb.Endpoint,
      path: "/"
    }
  ]

Link to this section Summary

Functions

Returns a specification to start this module under a supervisor.

Link to this section Functions

Returns a specification to start this module under a supervisor.

See Supervisor.