I’m writing a package to query relational data from your model.
By relational data, I mean a bunch of Dicts that have “foreign key” relationships between them. For example:
type alias Model =
{ users : Dict Int User
, posts : Dict Int Post
, comments : Dict Int Post
}
type alias User =
{ name : String }
type alias Post =
{ author : Int, title : String, content : String }
type alias Comment =
{ author : Int, post : Int, content : String }
The idea is to use “combinators” to build a query that describes the operations that need to be made in order to fetch certain item from the “database”.
For example, for our view we may need our data in a “denormalized” form:
type alias PostView =
{ author : User
, title : String
, content : String
, comments : List CommentView
}
type alias CommentView =
{ author : User, content : String }
We can write a query that describes how to get that data and then we can perform that query:
queryPostView : Int -> Query Model PostView
Query.perform (queryPostView 1) model
> Just { ... }
I’m requesting feedback:
About the whole idea. Is it a good idea, is it worthwhile having?
About the API. Which functions seem useful and which doesn’t?
To share some unpublished package documentation (for example for review), commit README.md and docs.json (generated with elm make --docs docs.json ) to a github repository and use the following query parameters:
I’ve had some similar ideas in the past so to me this is a great package that could pave the way to new ways to build Elm apps I’m totally on-board with this and see where it goes
Usually, as soon as I post question online, I find the answer: I’m those sort of people.
In this case, as soon as I posted the package for feedback I began realizing that it’s just a wrapper around the Maybe module, and that it provides no significant advantage besides not having to pass the Model around to every function.
Yet it was incredibly fun to write, and I learned a lot!
I still think the idea has potential. Seeing the Model as a database and building queries is interesting. But I think it would be more useful something to update the data without losing integrity. For example, it could be something like:
type Database
= Users
| Posts
| Comments
type IntegrityError
= UserNotFound Int
| PostNotFound Int
| CommentNotFound Int
schema =
Schema.create
[ Schema.describe Users UserNotFound .users []
, Schema.describe Posts
PostNotFound
.posts
[ Schema.foreignKey Users .author
]
, Schema.describe Comments
CommentNotFound
.comments
[ Schema.foreignKey Users .author
, Schema.foreignKey Posts .post
]
]
Database.query schema queryPostView model : Result IntegrityError PostView
Database.update schema updateQuery model : Result IntegrityError Model
Maybe there’s something in there that could be of use for you. The package is specific to an api format however the ideas should transfer (or so I think) to other stuff.
There’s also the good work @dillonkearns has done with his graphql lib that is worth taking a look at.