Code Monkey home page Code Monkey logo

Comments (24)

schickling avatar schickling commented on July 26, 2024 12

Update: We're currently working on a new kind of GraphQL server framework which doesn't require you duplicate your schema/resolver code while still making it easy to adjust/evolve your schema in an easy and (type-)safe way. (The best part: you won't have to think about schema delegation or mess with the info object which is quite difficult to wrap your head around for newcomers.)

from graphql-binding.

lastmjs avatar lastmjs commented on July 26, 2024 5

This blog post offers potential simple solutions to these issues: https://medium.com/@lastmjs/advanced-graphql-directive-permissions-with-prisma-fdee6f846044

It shows a simple way to automatically expose all generated queries and mutations, and to easily combine those with your own custom schema and resolvers. Copying schema information is kept to a minimum. Permissions are handled elegantly through custom directives. Let me know if you have any questions.

from graphql-binding.

kbrandwijk avatar kbrandwijk commented on July 26, 2024 2

@SpaceK33z No, that's not the case. You can just import it, by putting # import Query.posts from 'prisma.graphql' in your schema.graphql.

from graphql-binding.

arrowfunxtion avatar arrowfunxtion commented on July 26, 2024 1

@kbrandwijk Import doesn't automatically expose the imported type to client. It's only referencing, that being said, I still need to redefine the type to expose to the client.

My concerns is, say, I want to be able to expose automatically all the generated type from generated/prisma.graphql to the client without manually redefine on schema.graphql

from graphql-binding.

rcy avatar rcy commented on July 26, 2024 1

Not sure if this is the place to share, but I posted a PR #65 which adds an optional targetFieldName argument to forwardTo. I am in the process of migrating a large project from the graphcool framework to prisma, and want to leave as much dependent client/frontend code alone as possible. So now I can do:

allPosts: forwardTo('db', 'posts')

Basically, allow forwarding to db endpoints whose name doesn't match the app endpoint.

from graphql-binding.

nikolasburk avatar nikolasburk commented on July 26, 2024 1

Hey @webberwang, this is a great point! Have you seen nexus-prisma already? It provides a similar functionality as forwardTo and easily let's you expose and customize Prisma's CRUD operations.

Here is a simple example that shows how to setup a CRUD API for your Prisma models:

datamodel.prisma

type User {
  id: ID! @id
  email: String! @unique
  name: String
  posts: [Post!]!
}

type Post {
  id: ID! @id
  createdAt: DateTime! @createdAt
  updatedAt: DateTime! @updatedAt
  published: Boolean! @default(value: false)
  title: String!
  content: String
  author: User!
}

index.ts (GraphQL server code)

const Query = prismaObjectType({
  name: 'Query',
  definition(t) {
    t.prismaFields(['*'])
  },
})

const Mutation = prismaObjectType({
  name: 'Mutation',
  definition(t) {
    t.prismaFields(['*'])
  },
})

const schema = makePrismaSchema({
  types: [Query, Mutation],

  prisma: {
    datamodelInfo,
    client: prisma,
  },

}

schema.graphql (generated)

type Mutation {
  createPost(data: PostCreateInput!): Post!
  createUser(data: UserCreateInput!): User!
  deleteManyPosts(where: PostWhereInput): BatchPayload!
  deleteManyUsers(where: UserWhereInput): BatchPayload!
  deletePost(where: PostWhereUniqueInput!): Post
  deleteUser(where: UserWhereUniqueInput!): User
  updateManyPosts(data: PostUpdateManyMutationInput!, where: PostWhereInput): BatchPayload!
  updateManyUsers(data: UserUpdateManyMutationInput!, where: UserWhereInput): BatchPayload!
  updatePost(data: PostUpdateInput!, where: PostWhereUniqueInput!): Post
  updateUser(data: UserUpdateInput!, where: UserWhereUniqueInput!): User
  upsertPost(create: PostCreateInput!, update: PostUpdateInput!, where: PostWhereUniqueInput!): Post!
  upsertUser(create: UserCreateInput!, update: UserUpdateInput!, where: UserWhereUniqueInput!): User!
}

type Query {
  node(id: ID!): Node
  post(where: PostWhereUniqueInput!): Post
  posts(after: String, before: String, first: Int, last: Int, orderBy: PostOrderByInput, skip: Int, where: PostWhereInput): [Post!]!
  postsConnection(after: String, before: String, first: Int, last: Int, orderBy: PostOrderByInput, skip: Int, where: PostWhereInput): PostConnection!
  user(where: UserWhereUniqueInput!): User
  users(after: String, before: String, first: Int, last: Int, orderBy: UserOrderByInput, skip: Int, where: UserWhereInput): [User!]!
  usersConnection(after: String, before: String, first: Int, last: Int, orderBy: UserOrderByInput, skip: Int, where: UserWhereInput): UserConnection!
}

# ... and all other generated Prisma types

Also feel free to check out this 15min demo video that shows how to get started with nexus-prisma.

from graphql-binding.

webberwang avatar webberwang commented on July 26, 2024 1

@nikolasburk Thank you for the informative demo code. I have actually looked into the code-first approach. While it sounds great to have the single source of truth to be in the actual programming language, the syntax just isn't as appealing as SDL.

Would it be possible to use nexus-prisma along side the normal SDL, where I use nexus-prisma mainly, but use SDL to create custom Query/Mutations?


Edit:

I was able to use mergeSchemas to combine the nexus-prisma schema & the SDL schema. Then share schema across modules using import.

from graphql-binding.

lastmjs avatar lastmjs commented on July 26, 2024 1

Exactly, I'm pretty disappointed in Prisma's new direction

from graphql-binding.

nikolasburk avatar nikolasburk commented on July 26, 2024 1

the syntax just isn't as appealing as SDL

That's a great point, I definitely agree that SDL is extremely nice to read! I personally prefer having a type-safe API over an untyped string-based API to construct my schema. For me, it's enough that the SDL is generated and I can use it as foundation to discuss the API with my colleagues, I don't need it when initially implementing the schema. But that's just my subjective opinion and I think the other one is equally valid – so SDL-first by all means remains a valid approach for building GraphQL servers!

I also want to point out that while we believe that code-first is an amazing approach that solves a lot of problems, it is totally possible to keep using Prisma when building your schema SDL-first! This might require some more boilerplate (which can be alleviated by codegen tools like graphqlgen or graphql-code-generator) and not give you the same level of type-safety, but overall absolutely possible and if that's your preferred way, you should stick to it 🙂

from graphql-binding.

SpaceK33z avatar SpaceK33z commented on July 26, 2024

Can you come up with other scenarios where resolver forwarding falls short, and approaches to improve the entire experience surrounding resolver forwarding?

I think the biggest issue with forwardTo() by far is that you have to manually copy all the generated GraphQL code by Prisma to your own schema.graphql. So if you want to forward posts you'd have to copy and paste this:

posts(
    where: PostWhereInput
    orderBy: PostOrderByInput
    skip: Int
    after: String
    before: String
    first: Int
    last: Int
): [User]!

from graphql-binding.

SpaceK33z avatar SpaceK33z commented on July 26, 2024

Thanks, I did not know that 😅. Still learning GraphQL...

from graphql-binding.

ramsaylanier avatar ramsaylanier commented on July 26, 2024

Would it be possible to compare GraphQL schemas between the database and application using introspection and then determine which application queries don't have resolvers?

from graphql-binding.

arrowfunxtion avatar arrowfunxtion commented on July 26, 2024

@marktani I have no problem on performing auth checking using forwardTo. Instead of wrapping per node basis, I would wrap all the resolvers before passing it GraphQLServer configuration. My concern now is what I state on my previous comments

from graphql-binding.

ramsaylanier avatar ramsaylanier commented on July 26, 2024

@arrowfunxtion wrapping all of the resolvers with an auth check works if every query requires authentication. It's doesn't work if you want per query authentication.

from graphql-binding.

arrowfunxtion avatar arrowfunxtion commented on July 26, 2024

@ramsaylanier Nope, it works per query too. Basically the wrapper will check if the particular query needs an auth or authorization (defined in separate files, I called policies.js). If there is policy defined, then use the policy function, if not, let it pass

from graphql-binding.

schickling avatar schickling commented on July 26, 2024

That's a great suggestion and already a good step in the direction which I've laid out in this comment.

from graphql-binding.

schickling avatar schickling commented on July 26, 2024

@timsuchanek has written up some thoughts on how to push this forward. Curious to hear more thoughts on this: #83

from graphql-binding.

usulpro avatar usulpro commented on July 26, 2024

Hi! So what is the current status of this issue? is there a recommended approach for that?

from graphql-binding.

breytex avatar breytex commented on July 26, 2024

Bump, also interested in a minimal stack approach reducing duplicated schema code and trivial resolvers :)

from graphql-binding.

breytex avatar breytex commented on July 26, 2024

Hi @schickling,
that's brilliant news.
I tried to come up with a system as you described based on directives, but that gets messy very very quickly.

Can't wait to see it as a core feature.
Is there any way I can help? Joining development? Testing beta?

Thanks!

from graphql-binding.

webberwang avatar webberwang commented on July 26, 2024

For simple CRUD operations which happen often, having to specify resolvers is still cumbersome even with forwardTo().

Would be cool to have some sort of config that lets you set forwardAll: true.

prisma-labs/prisma-binding#383

from graphql-binding.

lastmjs avatar lastmjs commented on July 26, 2024

I'm glad SDL first is still possible. As for the argument about type safety, why can't someone just create plugins based off of the TypeScript language server or whatever that is called, but for the GraphQL language. TypeScript only gives you type safety because of the language tools around it. For example, lit-plugin uses those TypeScript tools to provide static type checking for HTML. I'm pretty sure the same kind of thing could be done for GraphQL

from graphql-binding.

webberwang avatar webberwang commented on July 26, 2024

@lastmjs You can generate types from schema.graphql using https://graphql-code-generator.com/

@nikolasburk Are there examples of how the front end gql queries can benefit from nexus? I couldn't find any so far. Would be awesome to be able to type gql Query/Mutation. Right now I can only type check the arguments to the gql Query/Mutation, but not the actual Query/Mutation itself.

Or does nexus allow createUser to be added to the react-apollo <Mutation mutation={createUser}/> as such?

Instead of

export const createUser = gql`mutation...`

2019-05-08_14-10-01

from graphql-binding.

Urigo avatar Urigo commented on July 26, 2024

Thank you for reporting.

In the last few months, since the transition of many libraries under The Guild's leadership, We've reviewed and released many improvements and versions to graphql-cli, graphql-config and graphql-import.

We've reviewed graphql-binding, had many meetings with current users and engaged the community also through the roadmap issue.

What we've found is that the new GraphQL Mesh library is covering not only all the current capabilities of GraphQL Binding, but also the future ideas that were introduced in the original GraphQL Binding blog post and haven't come to life yet.

And the best thing - GraphQL Mesh gives you all those capabilities, even if your source is not a GraphQL service at all!
it can be GraphQL, OpenAPI/Swagger, gRPC, SQL or any other source!
And of course you can even merge all those sources into a single SDK.

Just like GraphQL Binding, you get a fully typed SDK (thanks to the protocols SDKs and the GraphQL Code Generator), but from any source, and that SDK can run anywhere, as a connector or as a full blown gateway.
And you can share your own "Mesh Modules" (which you would probably call "your own binding") and our community already created many of those!
Also, we decided to simply expose regular GraphQL, so you can choose how to consume it using all the awesome fluent client SDKs out there.

If you think that we've missed anything from GraphQL Binding that is not supported in a better way in GraphQL Mesh, please let us know!


In the context of that particular issue - GraphQL Mesh uses a few interesting mechanisms like transforms and handlers, including using the new schema stitching introduced in GraphQL Tools v6 and Apollo Federation.
You can reuse underlining APIs, transform them in however way you like.
I believe it should give you a nice experience and power but if you think forwardTo in some way is missing in GraphQL Mesh, please feel free to open a new issue on the GraphQL Mesh repo.

We're looking forward for your feedback of how we can make your experience even better!

from graphql-binding.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.