Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nested Arguments #507

Closed
niqdev opened this issue Jul 16, 2020 · 7 comments
Closed

Nested Arguments #507

niqdev opened this issue Jul 16, 2020 · 7 comments

Comments

@niqdev
Copy link

niqdev commented Jul 16, 2020

Hi,

I'm trying to re-implement a very simplified version of the GitHub api to play with the pagination following the spec, but I'm not entirely sure how to represent the nested arguments. Could you please give me some hints?

Thanks in advance for the help!


Query example

query {
  user(login: "ghostdogpr") {
    id
    repositories(first: 2, after: "Y3Vyc29yOnYyOpHOA9J0lQ==") {
      totalCount
      edges {
        node {
          id
          name
        }
        cursor
      }
      pageInfo {
        endCursor
        startCursor
        hasPreviousPage
        hasNextPage
      }
    }
  }
}

This is a gist of my current schema

object queries {

  object arguments {
    final case class UserArg(login: NonEmptyString)
    final case class ForwardPaginationArg(
      first: Offset,
      after: Option[Cursor]
    )
  }

  final case class Queries[F[_]](
    // I don't know how to declare the pagination arguments for the nested "repositories" node
    user: UserArg => F[Option[UserNode]],
    // this works, but only because it's a root node and not what I want
    repositories: ForwardPaginationArg => F[RepositoryConnection]
  )
}

If needed, I can provide more details about the schema or the implementation, but I think they are neglectable

@ghostdogpr
Copy link
Owner

You can use arguments at any level of the schema: you just have the field return a function from the Arg case class to the result type. The same thing you did works whatever the level 😄

@niqdev
Copy link
Author

niqdev commented Jul 16, 2020

Whoo, thanks for the super fast replay!

🤔 Not sure i've understood correctly, should i change the query or the schema?

final case class Queries[F[_]](
   // ??? should i change the query with something like this?
    user: UserArg => ForwardPaginationArg => F[Option[UserNode]] => F[RepositoryConnection]
  )

// ??? or should i change the schema like this
final case class UserNode(
    id: NodeId,
    name: NonEmptyString,
    createdAt: Instant,
    updatedAt: Instant,
    repositories: ForwardPaginationArg => F[RepositoryConnection]
  ) extends Node

Could you give me a super simple example if i'm on the wrong track? Thanks 😊


This should give a full picture of what I got so far

object schema extends CommonSchema with CommonArgBuilder {

  @newtype case class Offset(value: NonNegLong)
  @newtype case class NodeId(value: Base64String)
  @newtype case class Cursor(value: Base64String)

  @GQLInterface
  sealed trait Node {
    def id: NodeId
  }

  final case class UserNode(
    id: NodeId,
    name: NonEmptyString,
    createdAt: Instant,
    updatedAt: Instant,
    //repository: Repository,
    repositories: RepositoryConnection
  ) extends Node

  // TODO add issue|issues
  final case class RepositoryNode(
    id: NodeId,
    name: NonEmptyString,
    url: String Refined Url,
    isFork: Boolean,
    createdAt: Instant,
    updatedAt: Instant
  ) extends Node

  final case class RepositoryConnection(
    edges: List[RepositoryEdge],
    nodes: List[RepositoryNode],
    pageInfo: PageInfo,
    totalCount: NonNegLong
  )

  final case class RepositoryEdge(
    cursor: Cursor,
    node: RepositoryNode
  )

  final case class PageInfo(
    hasNextPage: Boolean,
    hasPreviousPage: Boolean,
    startCursor: Cursor,
    endCursor: Cursor
  )
}

@ghostdogpr
Copy link
Owner

The second one ☝️

There is an example that shows nested effects here: https://github.com/ghostdogpr/caliban/tree/master/examples/src/main/scala/caliban/optimizations

Also this article might be of interest: https://medium.com/@ghostdogpr/graphql-in-scala-with-caliban-part-2-c7762110c0f9

@niqdev
Copy link
Author

niqdev commented Jul 16, 2020

Awesome, thanks a lot for the help and for the great lib!

One last question, is there any plan in future to add pagination and filter support directly in caliban, as an extra module? Or it's too specific cos might vary case by case, hence it's out of scope?

@ghostdogpr
Copy link
Owner

No immediate plan because each case is specific.

There was some interest from a few contributors to add some helpers for the Relay format so this might happen at some point.

@niqdev
Copy link
Author

niqdev commented Jul 16, 2020

Cool, I'm working on a standalone pr in my spare time (i haven't pushed the latest changes and I'm heavily iterating over it) with the goal to abstract it to create a lib, e.g. caliban-extras and I'd like to do the same for the filter using droste most likely.

I'm far from having anything close to be presented, but if you are interested, I could share it once it's ready and I'd be happy to contribute to this project - if it makes sense of course!

@niqdev niqdev closed this as completed Jul 16, 2020
@ghostdogpr
Copy link
Owner

Sure, feel free to drop by the Discord later if you want to discuss this with me and other contributors/users.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants