Complex resolves in absinthe types

Let’s say I have a User schema. Users have followers that are other Users (linked through a many_to_many in the schema), and they also can see a list of Newsfeeditems, that are associated through a query too complicated to be easily represented in the schema.

I want to craft a graphql query that gives me a User’s data, including his followers, and associated newsfeeditems. Without the newsfeeditems, this is easy:

  object :user do
    field :id, :integer
    field :handle, :string
    field :email, :string
    field :followers, list_of(:user), resolve: assoc(:followed)
  end

Very easy query and resolver. No idea what to do for the newsfeeditems though. Ideally, I would like to do something like this:

  object :user do
    # add this to the bottom V
    field :newsfeeditems, list_of(:newsfeeditem), resolve: &NewsfeedResolver.findNewsfeedByUserId/2
  end

The function being called takes an argument (the user :id) and looks like this:

  def findNewsfeedByUserId( %{user_id: user_id}, _info) do
    query =
      from f in Follow,
        where: f.following_id == ^user_id,
        join: n in Newsfeeditem,
        on: n.user1_id == f.followed_id,
        select: n

    case Repo.all(query) do
      nil -> {:error, "No profile items found"}
      profileitems -> {:ok, profileitems}
    end
  end

However when I make a query from graphiql, I get this:

** (exit) an exception was raised:
    ** (FunctionClauseError) no function clause matching in MyApp.NewsfeedResolver.findNewsfeedByUserId/2

That said, I am trying to figure out which of the three following solutions is best:

  1. Somehow implement the association above.

  2. Create a wrapper type and somehow do each of these queries.

  object :user_and_newsfeed do
    field :user, :user
    field :newsfeeditems, list_of(:newsfeeditem)
  end

(If I do this, would my query in schema.ex need to have two resolve arguments somehow? One for user and one for newsfeeditems?)

or

  1. Make two separate queries. Ugh, please not this.

Thanks!

Update: it turns out that you can just make multiple requests within one graphql query, which does exactly what I want.

query {
    user(id: 1) {
       ...
    }
    newsfeeditemsbyuser(userId: 1) {
       ...
    }
}

Still want to know if there is a way to implement #1 or #2.

1 Like