Comments (10)
Perfect, thank you so much for this input. 🎉
So, the reason you are experiencing this issue has to do with how GraphQL processes responses. I'll use SDL to present the idea, but I believe you should have no problem translating this into your schema as well.
GraphQL uses strongly typed language. That means that there's a particular "contract" between client and server which makes sure no result is unpredictable. My thinking is this; if I am querying type book by its id
and want to access id
, name
and content
field which are all non-nullable I rely on the fact that every single field in a book instance will have value once I get the result. This way, I don't have to write checks on the frontend to make sure every field, in fact, has a value.
Imagine a situation where one of the fields throws an error. In such a scenario, GraphQL can no longer ensure that all fields in Book
will have a value. Hence, to keep the contract trustworthy, it has to return null
.
GraphQL Shield works on a similar pattern; If the user has no access to a particular field, we throw an error. Makes sense, doesn't it? In your specific case, the problem is that secret
is non-nullable
field. Taking into consideration the above section, we can easily understand why in case the customer is not authenticated, user
returns null. If it weren't so, GraphQL would break the contract.
My vague remodelling of your schema looks something like this;
type Query {
node: User!
}
type User {
name: String!
...
secret: String!
}
Now to fix the error, you've probably guessed by now, you have to change non-null
secret to nullable
secret.
I hope this helps you solve the problem! 🙂
A quick advice; thinking of schema as a contract between your client and server could change the way you perceive it. For the field to be
non-nullable
, you have to ensure that no matter what, the client can receive it.
PS.: Check out node
Query field. Can you ensure that there will always be a user no matter the id
?
from graphql-shield.
You are right!
I missed the not-null.
Changing solved it.
Thank you very much!
PS: node
Query field called with wrong id
returns a not found
graphql error
from graphql-shield.
I have a big proprietary application I can't share but I assembled a strongly reduced but complete version to test the issue on.
Here is its schema
schema.txt
Permission are
const permissions = shield({ User: { firstName: allow, lastName: allow, secret: deny } });
Following query
{ currentUser { name } }
correctly give
{ "data": { "currentUser": { "name": "Paolo Rossi" } } }
Following query
{ currentUser { name secret } }
wrongly give
{ "data": { "currentUser": null }, "errors": [ { "message": "Not Authorised!", "locations": [ { "line": 5, "column": 5 } ], "path": [ "currentUser", "secret" ] } ] }
but I expected
{ "data": { "currentUser": { "name": "Paolo Rossi" } }, "errors": [ { "message": "Not Authorised!", "locations": [ { "line": 5, "column": 5 } ], "path": [ "currentUser", "secret" ] } ] }
or similar.
from graphql-shield.
Hey @AlessandroFerrariFood 👋
Could you share the chunk of your schema that is being affected? 🙂
from graphql-shield.
Hey,
I have a related issue to this. Let's say my schema looks like this:
type Resource {
id: ID!
createdBy: User
}
type User {
id: ID!
name: String!
}
I now have a field rule on Resource
to deny unauthenticated users from querying createdBy
.
When I now query Resource
unauthenticated like this:
{
resources {
id
createdBy {
id
name
}
}
}
I would have expected to get this result:
{
"data": {
"resources": [
{
"id": 1,
"createdBy": null
},
{
"id": 2,
"createdBy": null
}
]
}
}
But I get this:
{
"error": {
"errors": [
{
"message": "Not Authorised!",
"locations": [
{
"line": 4,
"column": 5
}
],
"path": [
"resources",
0,
"createdBy"
]
},
{
"message": "Not Authorised!",
"locations": [
{
"line": 4,
"column": 5
}
],
"path": [
"resources",
1,
"createdBy"
]
}
],
"data": {
"resources": [
{
"id": 1,
"createdBy": null
},
{
"id": 2,
"createdBy": null
}
]
}
}
}
Is there a way to suppress this error so it just returns null
for createdBy
and be done with it?
A bit more of context: In the app I'm working on I can't know which permission the user has, so I want to still be able to write the queries oblivious to this and just return null
to fields the user isn't allowed to query (as long as the fields are nullable of course) so I can handle it in the frontend. Is this something I can actually achieve with graphql-shield
?
from graphql-shield.
Hey, let's see what's going on!
tldr; I think the "problem" is on the frontend because it defaults to error and doesn't consume the data below
So, I think there are some settings regarding how client handles errors. What I wanted to ask before is how does the data in the error case relate to your schema (the rugs
part).
from graphql-shield.
Oh gosh, sorry. I wanted to edit the code I posted so it is more clear, but I forgot to edit the error part. I edited my original post.
The frontend itself isn't built yet, this is all from the playground.
I think it all boils down to this: If someone queries a nullable field without permission to access that field, I simply want to return null
instead of throwing an error.
from graphql-shield.
I think it all boils down to this: If someone queries a nullable field without permission to access that field, I simply want to return
null
instead of throwing an error.
It makes sense, no worries! 🙂
I mean, the easiest way to do that is to make fields nullable, as you mentioned. It's not possible to not throw a permission error, but that shouldn't be a problem, in my opinion.
Why's ignoring the error, and only collecting the data, not an option?
from graphql-shield.
Why's ignoring the error, and only collecting the data, not an option?
The problem I was facing is, that (when using nexus
framework) errors were returning 500
status codes. With this hack graphql-nexus/nexus#761 (comment) I was able to change it. Now it does return an errors
array but also the data
so I should be able to ignore it later
So I guess it was more of a nexus
issue than a graphql-shield
one, though I would've preferred to not throw an error but I get that this is probably not intended.
Thanks so much :)
from graphql-shield.
In case other people are looking for the same, link that @mkaradeniz is not existing any more (Maybe this one was the same?)
graphql-nexus/nexus#383 (comment)
For context, what we want to do, is format the response (in this case in apollo) so it will include the data also :)
const server = new ApolloServer({
// more config
formatResponse: (response, { operationName }) => {
if (response && operationName) {
return {
...response,
data: response.data || {
[operationName]: null,
},
}
}
return {
data: null,
}
},
})
from graphql-shield.
Related Issues (20)
- Execute root fields rules prior graphql execute phase
- Add the ability to use Fragments and post-execution rules with the single server/schema
- Add Typescript typings to rule args
- Add the ability to attach rules using GraphQL Directives
- CI: add codecov reports
- Provide a way to expose authorization metadata through the graphql schema
- GraphQL Shield Roadmap
- 7.6.4 ESM build broken HOT 5
- Documentation website down HOT 1
- How to use `if` condition in GraphQL Shield HOT 2
- Shield rules type generation based on schema HOT 1
- Feature request: wildcard functionality for field names
- Update [email protected] module to avoid @types/lodash and babel runtime in production deps
- fallbackError loses custom error types
- fallbackRule context information HOT 2
- Question: Is there a way to return objects on rules?
- ..
- Typo in the Docs
- Shield permissions only working properly with 'debug: true' HOT 1
- Performance -- every field wrapped is unnecessarily wrapped in a promise HOT 1
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-shield.