defmodule ExAws.Operation.JSON do
@moduledoc """
Datastructure representing an operation on a JSON based AWS service.
This module is generally not used directly, but rather is constructed by one
of the relevant AWS services.
These include:
- DynamoDB
- Kinesis
- Lambda (Rest style)
- ElasticTranscoder
JSON services are generally pretty simple. You just need to populate the `data`
attribute with whatever request body parameters need converted to JSON, and set
any service specific headers.
The `before_request`
"""
defstruct stream_builder: nil,
http_method: :post,
parser: &Function.identity/1,
error_parser: &Function.identity/1,
path: "/",
data: %{},
params: %{},
headers: [],
service: nil,
before_request: nil
@type t :: %__MODULE__{}
def new(service, opts) do
struct(%__MODULE__{service: service}, opts)
end
end
defimpl ExAws.Operation, for: ExAws.Operation.JSON do
@type response_t :: %{} | ExAws.Request.error_t()
def perform(operation, config) do
operation = handle_callbacks(operation, config)
url = ExAws.Request.Url.build(operation, config)
headers = [
{"x-amz-content-sha256", ""} | operation.headers
]
ExAws.Request.request(
operation.http_method,
url,
operation.data,
headers,
config,
operation.service
)
|> operation.error_parser.()
|> ExAws.Request.default_aws_error()
|> parse(config)
end
def stream!(%ExAws.Operation.JSON{stream_builder: nil}, _) do
raise ArgumentError, """
This operation does not support streaming!
"""
end
def stream!(%ExAws.Operation.JSON{stream_builder: stream_builder}, config_overrides) do
stream_builder.(config_overrides)
end
defp handle_callbacks(%{before_request: nil} = op, _), do: op
defp handle_callbacks(%{before_request: callback} = op, config) do
callback.(op, config)
end
defp parse({:error, result}, _), do: {:error, result}
defp parse({:ok, %{body: ""}}, _), do: {:ok, %{}}
defp parse({:ok, %{body: body}}, config) do
{:ok, config[:json_codec].decode!(body)}
end
end