flat file json or yml data layer
I have a very deeply nested JSON object that we think might be really nice to wrap a GraphQL query API over.
Unless I missed it, I don't see data layers similar to the CSV data layer that are targeting flat files in JSON/YML but I think the example of the CSV data layer would be a good starting spot in terms of seeing what needs to be implemented for the behavior.
I only really need to support read/query actions, and ideally I'd like to provide the data from the previous GQL field as the context for any child fields. I'm pretty sure I could devise a pretty quick strategy for this in Absinthe just based on dated but previous experience but I'm attracted to the resource model of ash and some of the adjacent functionality I could implement around the GQL API.
Is there a direction I should start in regards to read/query only access to flat files and context passing between associations that exist as sub-resources on a type that plays well with Ash OOTB? Is writing my own data layer the best or only design choice?
9 Replies
Hey there! Is this flat file information in a file that changes or doesn't change?
in the current strategy, the flat file would be read-only and any changes would be versioned objects in the same S3 location.
ah, okay but you can't do the work at compile time, you'll want to read the file on every request
right, it would be accessed via HTTP or S3 url, in the root query, was directionally what i was thinking.
rootQuery -> get s3 object
childField -> lens over object
nextChildField -> lens over childObject context
Each field would map to an Ash Resource, each resource would need to know how to take the input JSON and return resources
(well, either a property on the existing ash resource, or a nested one)
TBH I think you might be surprised at how easy it is to get what you want without needing to write a custom data layer. With the simple datalayer (the default) and some embedded resources you can get pretty much everything you want. If your structure is basically the same, you can do this:
If the embedded resources are mostly the same, then you can do things like add arguments to the create/update actions on those resources:
You could also use "regular elixir" to do said transformation in the preparation:
And finally, if you have lots of transformations you need to do and you want to do them lazily based on what is selected in the graphql, you would instead use calculations instead of attributes, for example:
and
GetFoo
would look like this:
And that calculation pattern should work for embedded resources too, so you can have a calculation that produces an embedded resource where you just set the json
attribute (which won't appear in the graphql), and then have calculations that will handle nested attributes.
One of those strategies ought to do the trick, and then Ash & AshGraphql will handle the rest for you@Zach Daniel this is such a thoughtful response, thanks so much, I'm gonna give this a go this week and see how it works out. Really appreciate it!
LMK how it goes!
The other nice thing about this set up is that your data will be filterable and sortable OOTB
We filter and sort in memory collections like what you’d return from your actions, so it will be filterable automatically via the generated graphql
yeh, thats part of what i was counting on, and granular policies on the resource layer
(Of course we do it in the database for other data layers)