Comments (24)
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.
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.
@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.
@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.
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.
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.
@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.
Exactly, I'm pretty disappointed in Prisma's new direction
from graphql-binding.
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.
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.
Thanks, I did not know that 😅. Still learning GraphQL...
from graphql-binding.
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.
@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.
@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.
@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.
That's a great suggestion and already a good step in the direction which I've laid out in this comment.
from graphql-binding.
@timsuchanek has written up some thoughts on how to push this forward. Curious to hear more thoughts on this: #83
from graphql-binding.
Hi! So what is the current status of this issue? is there a recommended approach for that?
from graphql-binding.
Bump, also interested in a minimal stack approach reducing duplicated schema code and trivial resolvers :)
from graphql-binding.
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.
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.
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.
@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...`
from graphql-binding.
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)
- Support webpack and other bundlers HOT 2
- typescript schema import breaks HOT 6
- Subscriptions are broken on 2.2.2 HOT 1
- Error when calling mutation that is specified inside "extend type Mutation" block HOT 4
- Experiment: using graphql-binding in client-side HOT 5
- Context object not getting sent HOT 2
- Is it possible to use batching? HOT 1
- How to dynamically update the link headers in the binding instance ? HOT 6
- Cannot use Alias with custom binding HOT 2
- [object Object] is returned from a binding when resolver throws an error HOT 14
- method cache and memory leaks HOT 3
- Cannot find module 'graphql/tsutils/Maybe' HOT 5
- mkdirp is not a function HOT 2
- mkdirp race condition HOT 4
- error data from binding is not available HOT 5
- How to write dynamic fragment to use with addFragmentToInfo
- Error with 'fs' and 'module' modules in front end HOT 1
- How can i custom resolves query connection which i expose from "forwardTo" HOT 1
- A new path for graphql-binding - help us decide on the roadmap! HOT 10
- Dependency Dashboard
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from graphql-binding.