Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
Yann Simon
@yanns
The federation support is very new. If you find some issues, it'd be great to add tickets on https://github.com/sangria-graphql/sangria-federated/issues
Greg Fisher
@gnfisher
Definitely will, thanks @yanns. Right now just a spike to see that I could get it working at all. When I get back to it I will open an issue if I can't figure out why the test suite raises that error but not the live server. Probably something about how I've set that test up.
Yann Simon
@yanns
@xsoufiane is the author of the federation library for sangria. He might be able to help also.
Yann Simon
@yanns
If you want to follow the progress of the scala 3 cross-compilation, and if you want to help, we've started a project: https://github.com/sangria-graphql/sangria/projects/2
(It's not exhaustive)
Nick Hudkins
@nickhudkins
Hi! Is it possible to call fetchers from within futures in resolvers?
Nick Hudkins
@nickhudkins
yes it is lol
Nick Hudkins
@nickhudkins
        def getFriendship(userA: String, userB: String): Future[Boolean] = Future.successful(true)

        resolve = _ => {
          getFriendship(userA, userB).map{ usersAreFriends => {
              if (usersAreFriends) {
                  fetchProfile.deferOpt(userB) 
              } else {
                  // TODO: How do I allow this to be None?
                  None
              }
          }}
        }
It feels to me that maybe this whole Future[Boolean] is a terrible idea and really it should be Future[Unit] and use .map(successResponse).recover(failureResponse)
Nick Hudkins
@nickhudkins
Actually no this ends up with the same problem which is that the response is lifted to a Future[Object] since map is evaluating to a Deferred and .recover is a NoneType. Perhaps I should simply sleep
Nick Hudkins
@nickhudkins
I suppose the semantics of GraphQL would also simply permit me to throw rather than attempt an explicit None, and maybe that's the right way to go about this
abhishekvaidprophecy
@abhishekvaidprophecy
Can someone urgently help me with this: sangria-graphql/sangria#676
Léonard Marques
@keuhdall

Hello, I'm pretty new to GraphQL and I'm encountering an issue with updating my entities in my mutation schema, the entity looks like this:

  Place {
    id: ID!
    name: String!
    city: String!
    pictures: [String!]!
    address: String
    description: String
  }

and the update mutation looks like this:

updatePlace ( id ID!, city String, pictures [String!], address String, description String ) Void!

Now my issue is, since address and description are optional fields, is there a way to differentiate in the mutation whether I'm not providing arguments for those fields (and therefore don't want to change their values), or if I do but I want to set them to null ?
Because as far as I know, in both cases I'll get None when calling c.arg() on my argument.
Thanks in advance !

3 replies
Srepfler Srdan
@schrepfler
@sh0hei will Scala 3 support also include support of native Union Types?
1 reply
spyros
@spyrosh_twitter
Hey all. Quick question: can I have a Query with a fieldType being an InterfaceType, instead of a concrete type that interfaces some InterfaceType? It compiles just fine, but sangria then complains with the "Can't find appropriate subtype of an interface type" error. Any help would be most appreciated!
1 reply
Mads Saustrup Fox
@MadsSaustrupFox
Hey, i have an issue. Would really like to have all the functionality of the Executor, but before it start to handle a query i would like to resolve/complete a future. I've hear it's not good practice to block the thread with Await.result. Is it posssible to have a step before execution where it fetches data from an external service. I have tried with middleware, but then it looks like i would have to await the result in beforeQuery, before i pass it on. Any suggestions or corrections to my design logic will be greatly appreciated
Yaroslav Derman
@yarosman
Hello. Can somebody show examples of using sangria for sealed hierarchies of case classes not objects ?
PsyfireX
@PsyfireX
Is it possible to combine deriveObjectType with Deferred values? For example if I have a case-class that is derived, and I want to have a single deferred field.
1 reply
PsyfireX
@PsyfireX

New Question:
https://sangria-graphql.github.io/learn/#actions

Is it possible for an Action to be a Future UpdateCtx? The basic idea is I want to return a Future, but also update the Ctx.

1 reply
Methrat0n
@Methrat0n
Hello all, how do I get the arguments of a sub-query ? Its one level deep.
I need it to paginate a database query and can't find any documentation about projections or even if its the right way to go.
1 reply
Tam-bhall
@Tam-bhall
Hi, I am new to sangria and resolvers in graphQL. Have a question, sorry if it sounds stupid:
What's the difference between sdl based schema resolvers and resolvers we create with static schema in scala object. And which one is better?
Ex: sdl based resolver is defined something like : AstSchemaBuilder.resolverBased("here we define DirectiveResolver")
And with static schema,
we define the type : implicit val ProductType: ObjectType[Unit, Product] = deriveObjectType[Unit, Product]
then : we have define fetcher(productFetcher) and finally we add it to DeferredResolver.fetchers(productFetcher)
3 replies
Tam-bhall
@Tam-bhall

Hi, I am back with another question:
I need to use schema first approach and have a schema like:

type Query {
    item(id: [String]!) : [Item]
}
type Item {
    itemId: String
    product: Product
}
type Product {
     productId: String
}

How do I write resolvers for list of inputIds above with nested entities using AstSchemaBuilder?

Tam-bhall
@Tam-bhall
Hi all, Follow up on above question, I tried creating resolvers one for Item and one for product for give list of ids. But it gives error "can't extract value of Product.productId". Is it with this approach graphQL can't know how to nest correct ids ?
I am thinking defining relation might help ? But I am stuck on how to define relations in SDL based approach ?
Sorry if duplicate.
Tam-bhall
@Tam-bhall
Sorry I am asking so many questions.
So if I understand correctly,
  1. we can't use DeferredResolver mechanism with SDL based approach?
  2. But DeferredResolver are much more efficient than SDL based directive or field resolver ?
  3. Also looks like we can't define Relations in SDL based approach ? I couldn't find much documentation on this.
    I have requirement on schema first approach but just want to make sure on pros and cons.
    Thanks in advance. Please help with clarifying these.
kamisama-rney
@kamisama-rney

Hi,

We've been using Sangria to create our company's first GraphQL APIs. We're a Scala Functional programming shop so we like doing everything monadic. We're doing our first schema that does a large number of fetches from DynamoDB tables to realize the result schema and I'm trying to use the Fetcher type for each sub-table. This method expects a Future returned from the repository function while our is returning a higher-type of F[Seq[Software]]. Have others been using Functional types with the Fetchers and Resolver caches? Sample code block below

  def softwareFetcher[F[_]: Effect] = 
    Fetcher((repo: MasterRepo[F], ids: Seq[String]) => repo.devicesRepo.softwareByDeviceGuids(ids))(HasId(_.deviceGuid))
6 replies
Bryan
@Bryji
Does Sangria support namespaces? (how do implement the resolver, the "magic" as discussed here: https://graphql-rules.com/rules/mutation-namespaces)
Performant Data
@performantdata

Correct me if I'm wrong, but...

I get the impression that https://github.com/sangria-graphql/sangria-akka-http-example is using https://github.com/graphql/graphql-playground and that the latter has been ended in favor of GraphiQL. graphql/graphql-playground#1143

I've incorporated GraphiQL into a Sangria server before using webjars. Is this something that needs to be done?

Performant Data
@performantdata
This message was deleted
1 reply
Performant Data
@performantdata
Shouldn't sangria-akka-http-example have something more like a CC0 license?
Nick Hudkins
@nickhudkins
Hey @performantdata, I didn’t know GraphQL playground was merging. Just saw your PR, I’ll add some comments there
JayalakshmiH
@JayalakshmiH
Hi all, I am pretty new to Sangria. Need some examples for resolving union types. For .js implementation, i see that we need to add __resolveType function to resolve unions. I am wondering how it has to be done in case of Sangria. If someone could provide some examples, it would be great. Thanks!
JayalakshmiH
@JayalakshmiH

Following up on my previous question on union type, have made changes to return all possible types of union as a default case. But I wanted to add check based on the __typename requested for. I see in .js, objects are resolved based on the unique field name that each type has. Am looking for something equivalent in sangria.

__resolveType: obj => {
if (obj.reason) {
return "TimeoutError";
}

  if (obj.field) {
    return "ValidationError";
  }

  return null;
}
Nick Hudkins
@nickhudkins
Can you describe more in detail your use case and maybe what the query would be in the case you need to check for the type being requested? This sounds a lot like implementing the node interface like in the relay spec.
Nick Hudkins
@nickhudkins
https://github.com/sangria-graphql/sangria-relay-playground/blob/main/app/models/SchemaDefinition.scala take a look here for how that behaves. The information about type name is encoded in the ID requested.
Nick Hudkins
@nickhudkins
For example, how would you expect this query to behave? The way GraphQL would deal with this is that the server would return either a UnionTypeA or a UnionTypeB, and you would receive a response for just that type. If you are hoping to have the type defined by the user, you would either need some sort of input arg to someUnionField or, better yet, split this into two distinct fields rather than 1 that is a union type. Am I understanding correctly?
{
     someUnionField {
          ... on UnionTypeA {
                someFieldOfTypeA
           }
           ... on UnionTypeB {
                someFieldOfTypeB           
            }
     }
}
JayalakshmiH
@JayalakshmiH
For the scenario, that you mentioned above, i wanted to return both UnionTypeA and UnionTypeB. For example, if client requests only for UnionTypeA, then I wanted to return only UnionTypeA. In order to implement that, I wanted to know which UnionType the client is requesting for. Is there a way to get that?
{
someUnionField {
... on UnionTypeA {
someFieldOfTypeA
}
}
Nick Hudkins
@nickhudkins
Not that I can think of. The issue is that you could spread multiple fragments, so how would you decide what to send in the case of multiple. This SOUNDS like two distinct fields to me. Alternatively, take some sort of input to “someUnionField” but the fragment itself is not “input” so to speak
Léonard Marques
@keuhdall
Hello everyone,
I'm trying to setup access control in Sangria, basically I'm authenticating on client side through Auth0 and then make the query with the bearer as Authorization header, I then validate the token and retrieve the user's identity from the database (all this happens before call Executor.execute), but so now that I have my user's identity and its roles, I don't really know what to do...
I tried following Sangria's documentation (https://sangria-graphql.github.io/learn/#authentication-and-authorisation), however the part about that SecureContext really confuses me.
If my understanding is correct, I should first create a SecureContext that holds an Option[Identity] defaulting to None, and update that context after I retrieved my user's Identity, and then perform my access control against that updated context.
Sorry if my question sounds a little silly, but can someone confirm / correct my understanding of the process ?
Thank you !
Nick Hudkins
@nickhudkins
If you have an Option[Identity] before you call Executor.execute, you can add that as a field on whatever you’re constructing for userContext. No need to do any context updates, simply build it before you execute!
2 replies
Nick Hudkins
@nickhudkins
Because I’m a dummy 😂
Léonard Marques
@keuhdall
Hello again,
I made good progress on my authorization middleware, but I have a few more questions.
So far I went with a middleware-based auth instead of a resolve-based auth.
However, this seem to cause issues for me for the following use case:
Let's assume I have a Book entity, that has a userId attached to it, and a user can only query his books, how can I ensure that the Identity I'm holding from the Bearer token is matching the Id given in the query ?
Since beforeField has my Context as parameter, my guess is that I can check the arguments passed, as one of them would be my userId , but let's assume the argument I want to check varies from one query to another (like, not necessarily called 'Id', or 'userId'), is there a way to use Middleware-based authorization anyway, or should I use Resolve-based authorization ?
Thank you !
Yann Simon
@yanns

I don't think it's middleware VS resolve-based auth. We are using both for example.
The middleware checks that we are logged in.
The middleware also checks permissions based on tags:

val permissions = ctx.field.tags.collect { case Permission(p) => p }
      if (permissions.nonEmpty && !secureContext.hasPermissions(permissions))
        throw GraphQLOAuthException(OAuthError.insufficientScope(permissions))

And then, in some resolve functions, we also check the permissions:

      resolve = (c: Context[SecureContext, Unit]) => {
        if (!c.ctx.hasPermissions(....))
          throw GraphQLOAuthException(OAuthError.insufficientScope)
1 reply
Justin Reeves
@clutch-justin
Trying to make a ScalarType[JsValue] to merge an arbitrary JsValue into a response ({} or {"foo": "bar"}) for example , but getting java.lang.IllegalArgumentException: "Unsupported scalar value: {}"
  case object JsonCoercionViolation extends ValueCoercionViolation("Not valid JSON")

  implicit val JsonType: ScalarType[Any] = ScalarType[Any]("Json",
    description = Some("Raw JSON value"),
    coerceOutput = {
      case (value: JsValue, c) => value
    },
    coerceUserInput = {
      case v: String => Right(JsString(v))
      case v: Boolean => Right(JsBoolean(v))
      case v: Int => Right(JsNumber(v))
      case v: Long => Right(JsNumber(v))
      case v: Float => Right(JsNumber(v))
      case v: Double => Right(JsNumber(v))
      case v: BigInt => Right(JsNumber(BigDecimal(v)))
      case v: BigDecimal => Right(JsNumber(v))
      case v: JsValue => Right(v)
      case _ => Left(JsonCoercionViolation)
    },
    coerceInput = {
      case ast.StringValue(s, _, _, _, _) =>
        Right(Json.parse(s))
      case _ =>
        Left(JsonCoercionViolation)
    })
Justin Reeves
@clutch-justin
I'm just proxying another service.
I found this https://gist.github.com/OlegIlyenko/5b96f4b54f656aac226d3c4bc33fd2a6 and tried it but for Play Json, but still get the above result...(or issues trying to use two ResultMappers at once)
I get this can be an issue, but is there away to make a particular field just returns some json?
Justin Reeves
@clutch-justin
I got it by adding the same case v: JsValue => v to the ResultMarshaller...which is the opposite of what Ithought I had to do
Performant Data
@performantdata

I'm puzzled as to why this variables field in GraphQLHttpRequest has a type parameter (and thus why GraphQLHttpRequest itself does). It seems like this should just be represented as a Map[String,String], possibly empty.

case class GraphQLHttpRequest[T](
    query: Option[String],
    variables: Option[T],
    operationName: Option[String])

https://github.com/sangria-graphql/sangria-akka-http/blob/5411bedfc7a4d6c07deebb424d0cc5a4db33baf5/core/src/main/scala/sangria/http/akka/GraphQLHttpRequest.scala#L5

3 replies
Rishi Khandelwal
@rishckt_twitter

How can we pass List[List[caseClass]] as argument ? When I am trying to do so, I am getting the following error: "spray.json.JsArray cannot be cast to scala.collection.Seq"

val fdsInputRequestFilter: InputObjectType[RequestFilter] = deriveInputObjectTypeRequestFilter

val requestFilter = Argument("filters", OptionInputType(ListInputType(ListInputType(fdsInputRequestFilter))))

Any help will be appriciated.