AF
Ash Framework•2mo ago
rellen

Loading data from an external API for a calculation

Hello! I have a resource that I would like to enhance in certain reads with a calculation that needs to be based off data from an external API. I'm mindful of not wanting to make the API request from within a transaction if possible. I thought of adding a preparation to the read action that will fetch the API data and put it into the context, which the calculation can use.
# preparation module
Ash.Query.before_transaction(query, fn query ->
api_data = make_external_api_call()
Ash.Query.put_context(query, :external_api_data, api_data)
end)

# calculation module
def calculate(records, _opts, context) do
api_data = context.source_context[:external_api_data]
Enum.map(records, fn record ->
# get apppropriate field from api_data
...
end)
end
# preparation module
Ash.Query.before_transaction(query, fn query ->
api_data = make_external_api_call()
Ash.Query.put_context(query, :external_api_data, api_data)
end)

# calculation module
def calculate(records, _opts, context) do
api_data = context.source_context[:external_api_data]
Enum.map(records, fn record ->
# get apppropriate field from api_data
...
end)
end
Is this a reasonable approach? Are there any escape hatches to be able to avoid decoupling the API request from the calculation module while still ensuring the request runs outside of a transaction?
Solution:
🤔 yeah, its not great but that is probably the best way. YOu will likely want to switch on whether or not the given calculation is being loaded
Jump to solution
3 Replies
Solution
ZachDaniel
ZachDaniel•2mo ago
🤔 yeah, its not great but that is probably the best way. YOu will likely want to switch on whether or not the given calculation is being loaded
ZachDaniel
ZachDaniel•2mo ago
so you don't always do that work
rellen
rellenOP•4w ago
It's worth following up here that the calculation probably won't run inside the transaction if it's loaded as part of a read action etc that itself starts a transaction. So it may be simpler to put the API call in the calculation and avoid the preparation and passing data through the context.

Did you find this page helpful?