Package to query relational data from your model

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:

  1. About the whole idea. Is it a good idea, is it worthwhile having?
  2. About the API. Which functions seem useful and which doesn’t?

Here you can preview the docs:
Here is the repo:

Thanks :slight_smile:

Edit: I don’t know how to make elm-doc-preview to show the documentation of the modules in the online version :frowning:

1 Like

You need to commit the generated docs.json. :slight_smile:

Sharing documentation

To share some unpublished package documentation (for example for review), commit 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 :slight_smile: I’m totally on-board with this and see where it goes

Awesome, thanks!

Thanks for the kind words :slight_smile:

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.describe Users UserNotFound .users []
        , Schema.describe Posts
            [ Schema.foreignKey Users .author
        , Schema.describe 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

You may be able to take a more static approach (instead of using Dict) to get some nice benefits.

I’ve done a bit of work in this area here:

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.

1 Like

I’m not exactly sure if you’re aiming for something different but seems like an useful reference for manipulating local structures.

1 Like

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.