I have a Struct that I am hydrating from a GraphQL response from Github:
defmodule MyThing.Github.PullRequest do
defstruct [:title, :approvals] # and a lot of other fields
end
The :approvals
fields and some other fields are dynamic based on the content of the response. For example, I’m looping over the reviews for a given pull request. I do that by having a consumer of the request call a from_response
method on the struct module:
defmodule PullRequest do
defstruct [:title, :approvals] # and a lot of other fields
def from_response(response) do
struct( __MODULE__, { approvals: approvals(response) })
end
defp approvals(response) do
response["reviews"]
|> Enum.map(& &1["kind"])
|> Enum.filter(& &1 == "APPROVAL")
|> Enum.count
end
end
The usage would look something like:
pull_requests = GitHubRequest() |> Enum.map(&PullRequest.from_response/1)
The current approach works but feels a little too close to what I would do in Ruby (albeit with a class’s initialize
or methods on a struct).
What is the idiomatic way of handling this in Elixir? I’d prefer to have the struct initialized with the correct data one time and not make every consumer of the struct call different methods to calculate the “dynamic” fields.