graphql-go-tools icon indicating copy to clipboard operation
graphql-go-tools copied to clipboard

How do you use this library? Please tell me to help improve it!

Open jensneuse opened this issue 6 years ago • 13 comments

As the title says, please tell me how you use this library. This helps me better understand your use case and evolve the library in the right direction. It's open source so any feedback improving the library is well appreciated.

jensneuse avatar Jan 16 '20 14:01 jensneuse

@jensneuse I consider this library for implementing a gateway server (must support GraphQL subscription operations ) for graphql federation.

I would like to clarify some questions regarding the future of this library.

  1. Are there still plans to add a tool #230 which introspects multiple federated services and automatically configures everything ?
  2. There are 2 execution engines, are you planning to support both versions? It seems as ExecutionEngineV2 does not support subscriptions

chedom avatar Mar 23 '21 10:03 chedom

@jensneuse I consider this library for implementing a gateway server (must support GraphQL subscription operations ) for graphql federation.

I would like to clarify some questions regarding the future of this library.

  1. Are there still plans to add a tool #230 which introspects multiple federated services and automatically configures everything ?
  2. There are 2 execution engines, are you planning to support both versions? It seems as ExecutionEngineV2 does not support subscriptions
  1. It's currently not planned
  2. Internally, subscriptions are supported, just not exposed in the graphql package

The graphql package is a wrapper to make using the library easier. If you have patience, subscriptions will be added in the next months to the graphql package. If you don't, I'm open to your PR to add it.

jensneuse avatar Mar 23 '21 10:03 jensneuse

I'm currently building a tool which introspects multiple federated services and automatically configures everything for you. I'll keep you posted once done.

It's currently not planned

The existence of such tool is critical for my case (there are several dozen of federated servers). I have added some types for building base schema from SDLs and creating datasource config from created schema and SDLs. I have also added example how to configure federation gateway server. If you see the sense in what I have done, I can create PR. If something is missing or needs to be redone, I am open to fix it.

chedom avatar Apr 09 '21 15:04 chedom

Please open a PR and I'll have a look.

jensneuse avatar Apr 09 '21 15:04 jensneuse

I'm currently building a tool which introspects multiple federated services and automatically configures everything for you. I'll keep you posted once done.

It's currently not planned

The existence of such tool is critical for my case (there are several dozen of federated servers). I have added some types for building base schema from SDLs and creating datasource config from created schema and SDLs. I have also added example how to configure federation gateway server. If you see the sense in what I have done, I can create PR. If something is missing or needs to be redone, I am open to fix it.

What's the reason you've closed the PR? Should the code be merged or not?

jensneuse avatar Apr 11 '21 08:04 jensneuse

I found that my branch is out of sync with the latest changes in master. I have updated and create a new #250 PR.

chedom avatar Apr 11 '21 12:04 chedom

@jensneuse I'm trying to implement a dynamic graphql-gateway, it should update its resolvers whenever datasources change its schemas. My core problem is the lack of documentation. I've seen docs here and I've read tests, but it's not enough to understand which approach I should choose to satisfy my requirements. It would be great if you add more comments to core structures such as planner, executor, datasource, engine, etc, and if there are some examples of how to use each of them. Or if you write some docs providing a base explanation of main concepts with some best practices. Thanks in advance.

germankrause avatar Jun 07 '21 16:06 germankrause

@jensneuse I'm trying to implement a dynamic graphql-gateway, it should update its resolvers whenever datasources change its schemas. My core problem is the lack of documentation. I've seen docs here and I've read tests, but it's not enough to understand which approach I should choose to satisfy my requirements. It would be great if you add more comments to core structures such as planner, executor, datasource, engine, etc, and if there are some examples of how to use each of them. Or if you write some docs providing a base explanation of main concepts with some best practices. Thanks in advance.

Hey, thanks for reaching out! You didn't provide much info but I think this library can help you very well achieving your goal.

Hey, there's a few things we can do:

  1. You can open a PR and submit better documentation (possible but unlikely due to lack of understanding)
  2. You could pay me a few hours which I will spend to address the issues you mention. That is, write docs dedicated to solving your use case, maybe create an example. This will not just benefit you but also the community.
  3. You could buy consulting/support, we'll analyze your use case in-depth and I'll guide you on how to properly use the library to solve your problems.

Feel free to contact me on Linkedin to continue the discussion: https://www.linkedin.com/in/jens-neuse-706673195/

jensneuse avatar Jun 07 '21 17:06 jensneuse

Hi @jensneuse

I'd like to build a thin proxy that acts as a rewrite layer to modify some queries and mutations:

Client <--- Fully Typed GraphQL API ---> Proxy <--- Loosely Typed GraphQL API ---> Server

  • In my original graphql server (hasura or dgraph) I store serialized JSON in plain-text
  • string fields that should be marshalled/unmarshalled by the proxy do have comments attached that specify their actual type

server-api.graphql

type User {
  username: String!
  """
  type: Foo!
  """
  foo: String!
}

type Query {
   getUser: User!
}

input UserInput {
   username: String!
   """
   type: FooInput!
   """
   foo: String!
}

type Mutation {
   addUser(input: UserInput): User!
}

In another file, I maintain the actual type representations as GraphQL types that my proxy should offer: jsonTypes.graphql

type Foo {
  a: Int
  b: Int!
  bar: Bar!
}

type Bar {
  names: [String!]!
}

input FooInput {
  a: Int
  b: Int!
  bar: BarInput!
}

input BarInput {
  names: [String!]!
}

The expected client-side API:

type User {
  username: String!
  foo: Foo!
}

type Query {
   getUser: User!
}

input UserInput {
   username: String!
   foo: FooInput!
}

type Mutation {
   addUser(input: UserInput): User!
}

The proxy that I want to build, should read the original server-api-schema + the jsonTypes.graphql and offer a new endpoint where all fields that have type: <> comments are replaced by their actual object types defined in jsonTypes.graphql When a request is made that contains such a type, the graphql object should be serialized/deserialized and forwarded either as the actual graphql type to the client or as a serialized JSON string to the server.

All other requests (queries/mutations/subscriptions) that do not use types defined in jsonTypes.graphql should be forwarded just directly to my server.

I already figured out the schema transformation part using vektah/gqlparser. So I already have a server-side schema and a client-side schema.

  • How can I transform an github.com/vektah/gqlparser/v2/ast.Schema to the schema representation used by graphql-go-tools?
  • What steps are missing to build the wanted proxy service with graphql-go-tools?

maaft avatar Jun 08 '22 11:06 maaft

@maaft can you explain what your goal is from an architectural perspective? Like, why do you want this architecture? What problems does it solve for you?

jensneuse avatar Jun 08 '22 13:06 jensneuse

It solves the problem of storing untyped JSON (i.e. strings) in GraphQL-enabled databases (Hasura, Dgraph et al. ) but having a fully-typed client-facing GraphQL API at the same time.

Added benefits when dealing with untyped JSON at a DB level:

  • input validation for all JSON data
  • schema introspection (typed clients) for JSON fields

This mutation is what you have to do from a client when talking directly to hasura or dgraph

mutation {
 insert_users_one(object: {
   foo: "<a long serialized JSON string"
 }) {
  user {
     foo # <-- also a long serialized json string
  }
}
}

This mutation would be possible with the mentioned middleware:

mutation {
 insert_users_one(object: {
   foo {
      a: 0
      b: 1
      bar {
          names: ["alice", "bob"]
      }
   }
 }) {
   user {
      foo {
         a
         b
         bar {
            names
         }
      }
   }
}
}

maaft avatar Jun 08 '22 14:06 maaft

@maaft This is interesting, I think we've already solved this problem with WunderGraph, which is built on top of graphql-go-tools. https://wundergraph.com/docs/guides/strategies/using_json_columns_with_a_custom_graphql_schema

Let me know if this solves your problem.

jensneuse avatar Jun 08 '22 15:06 jensneuse

PUBLISHED: 2022-06-08

happy to help :D

yes, this sounds exactly like my usecase. Will look into it - thanks!

maaft avatar Jun 08 '22 20:06 maaft