View Source BridgeEx
A library to build bridges to other services (actually only graphql ones are supported).
Usage
A GraphQL bridge
Define a behaviour with the queries/mutations you're going to need for the bridge:
defmodule MyApp.SomeService do
@moduledoc """
Bridge definition for SomeService
"""
@callback my_cool_query(any()) :: {:ok, map()} | {:error, any()}
end
Implement the behaviour:
defmodule MyApp.SomeServiceBridge do
@moduledoc """
Bridge implementation for SomeService behaviour.
"""
@behaviour MyApp.SomeService
use BridgeEx.Graphql, [
# mandatory settings
endpoint: "http://some_service.example.com",
# optional settings (with defaults)
http_headers: %{
"User-Agent" => "microservice-myapp/myapp-version",
"Content-type" => "application/json",
"X-Client-Id" => "myapp",
"X-Client-Secret" => "myapp_secret"
},
http_options: [timeout: 1_000, recv_timeout: 16_000],
max_attempts: 1,
encode_variables: false,
format_response: true, # formats keys from CamelCase to snake_case
log_options: [log_query_on_error: true, log_response_on_error: false]
]
def my_cool_query(%{} = variables) do
call("a graphql query or mutation", variables)
# or, if you need more granularity (ex: different endpoint or options):
# BridgeEx.Graphql.Client.call(
# "https://another-url.com/graphql",
# "graphql query or mutation",
# variables,
# encode_variables: false,
# [timeout: 1_000, recv_timeout: 16_000],
# %{
# "Some-Header" => "some-value",
# },
# 1
# )
end
end
You can now use your bridge module:
MyApp.SomeServiceBridge.my_cool_query(%{var: 1})
As a good practice, if you want to mock your bridge for testing, you should implement another module:
defmodule MyApp.SomeServiceBridgeMock do
@behaviour MyApp.SomeService
alias BridgeEx.Graphql.Utils
def my_cool_query(%{} = variables) do
File.read!("some_mock_file.json")
|> Json.decode!(keys: :atoms)
|> Utils.parse_response() # required to parse data
# |> BridgeEx.Graphql.Client.format_response() # optional, if you want to format response
end
end
You can now set the right module in your config/*
directory:
config :my_app, :some_service_bridge, MyApp.SomeServiceBridge
# or
config :my_app, :some_service_bridge, MyApp.SomeServiceBridgeMock
And use it in your app from configuration:
@some_service Application.compile_env!(:my_app, :some_service_bridge)
# ...
@some_service.my_cool_query(%{var: 2})
See example directory for an implementation, it also works in dev
and test
environments.
Authenticating calls via Auth0
bridge_ex
supports authentication of machine-to-machine calls via Auth0, through the prima_auth0_ex library.
To use this feature, simply configure your bridge with the audience of the target service:
use BridgeEx.Graphql, [endpoint: "...", auth0: [enabled: true, audience: "target_audience"]]
For this feature to work, your config.exs
must be updated with the configuration for the prima_auth0_ex
library.
You can refer to the library's README for more information on the supported configuration.
Development
mix deps.get && mix test
Installation
The package can be installed by adding bridge_ex
to your list of dependencies in mix.exs
:
def deps do
[
{:bridge_ex, "~> 0.4.0"}
]
end
Copyright and License
Copyright (c) 2020 Prima.it
This work is free. You can redistribute it and/or modify it under the terms of the MIT License. See the LICENSE.md file for more details.