Comments (9)
Might be that I should have created that in spec repository, I can move it if you want.
from graphql-js.
No problem for it to be here, this is a great question we spent a lot of time talking about when assembling the spec.
Ultimately, we decided that it was beneficial for the return type of a field to always be the same regardless of arguments (e.g. no overloading) because it dramatically simplifies introspection which means less friction to building great tools.
We work around that in two ways:
If you know the type that is going to be returned apriori, then it's best if your type system exposes a field that documents that. It allows tools to be smarter and often is nicer to read. To build upon your example:
{
user(id: "...") {
// Stuff here is type checked as User
}
invalidType(id: "...") { // this is now statically known to be a bad query
// ...
}
otherType(id: "...") {
// checked as OtherType
}
}
For fields on the top level, this pattern of someType(id: 123)
is very common for the same reason SELECT * from someType where id = 123
is the most recognisable SQL :)
For fields where you can't apriori know the exact return type, and you're using one of the abstract types (interface types and union types) then fragments are the tool to use. Here's an example showing inline fragments, which are useful for this case, but you could also use defined and referenced fragments to identical effect:
{
node(id: "...") {
// Stuff here could be one of many possible types at runtime!
... on User {
// Stuff here is type checked as User
}
... on InvalidType { // statically known to be bad
// ...
}
... on OtherType {
// checked as OtherType
}
}
}
We use this pattern a lot at Facebook, where we refer to a lot of things generically. For example if we're trying to load data to prepare facebook.com/12345
, then 12345
could refer to a User, a Page, an App, an Event, in addition to a lot of things. We won't know which type until we execute and we need dramatically different fields depending on which type it is. Fragments is how we handle this case.
from graphql-js.
Thanks!
Follow-up question - in our system user there are calls to dynamically update the schema, eg createType
, createField
, createRelation
. Naturally, stuff that modifies types, like createField
, deleteType
accepts type as a first argument.
{
deleteType(type: "User") {
// Result here is probably __Type
}
}
Should type
here be an Enum
of all types (that can be deleted)? Does/should GraphQL expose that enum already?
from graphql-js.
That's pretty cool that you've got a dynamic schema like that. One thing to be cautious of is to ensure that "breaking changes" to an API like this won't break any existing consumers of your API, but there are definitely circumstances where this sort of dynamic schema is powerful. Fast prototyping comes to mind.
We don't present type names as an Enum, we considered it but decided that it was an unnecessary complication. There are definitely some perks like ensuring statically that any references to types are correct, but there are really just a few places where that's the case. You could also imagine that with a dynamic schema API like that, it could be easy for the Enums to get out of sync if two clients are calling createType
and deleteType
and the Enum value list also have to be updated. And at Facebook, our GraphQL API is now really huge with hundreds or maybe even thousands of types, at which point the Enum gets unwieldy.
from graphql-js.
I don't really see a way to prevent such race conditions apart from locking the API during schema changes, which isn't very developer-friendly. We assume people would use best judgment and won't modify their schema too much when they are out in production. It seems to work fine for, eg, Parse.
As for dynamic schema - we just serialize parts of the schema that can be modified and restore the schema to 'native' format before query execution. Our schema language is quite similar to the one in reference implementation (albeit much more crude and hacked together), so it shouldn't be a big problem for us to move to FB schema language.
from graphql-js.
Absolutely, just something to keep in mind. I would be cautious of any kind of schema-modifying public API for a public service because of nefarious actor concerns (what happens if someone runs deleteType("User")
on your site?) but for prototyping its an awesome capability and in that context racing is not so important.
Thanks for the great questions!
from graphql-js.
@leebyron sorry to necromance this issue but we're having trouble using this polymorphic functionality. When requesting by interface name, the returned values are also of the interface type, not of the concrete type. We can try to introspect via __typename
but that seems unwieldy (and doesn't appear to be accessible on the client)
How can we find out the specific types of items returned when querying by interface?
from graphql-js.
When requesting by interface name, the returned values are also of the interface type, not of the concrete type.
Can you expand on this? Perhaps with some links to code examples?
The purpose of __typename
is exactly to query the concrete type by clients.
from graphql-js.
It seems like we may have had a bad release, upgrading to latest graphql-js fixed __typename
behavior on client. Thanks for your prompt reply!
from graphql-js.
Related Issues (20)
- IHeyReally.org
- Suggestion: Bundling in v17, ESM, CJS, and the dual package hazard HOT 9
- Just to give my 2c, I'm not sure if `exports.development` and `exports.production` target conditionsa are widely supported, so some `import.env` shenanigans may still be necessary until that's widely adopted. HOT 1
- Collection of libraries and how they import from `graphql` HOT 20
- `process.env`, `globalThis`, and `typeof process` HOT 21
- Introspection queries don't support `@oneOf` HOT 2
- Tutorial data HOT 2
- astFromValue fails with a custom scalar serializing to an object value HOT 5
- In a response to a query about an Issue, the URL and other info is missing for links created with Reference editor button HOT 5
- author/committer -> user fields returning NULL for commits committed by user
- [email protected]
- npm link with graphql package breaks application HOT 2
- IHeyReally.com HOT 1
- Can I ask what is the progress here? Is there a solution being worked on? Do we have some timeline? Or progress with issue? Thanks!
- IHeyReally.com
- Typescript error with 16.9.0 (re ThunkObjMap) HOT 3
- Notice: default branch is now `16.x.x` HOT 2
- <a href="https://api.easycla.lfx.linuxfoundation.org/v2/repository-provider/github/sign/12261526/38307428/4135/#/?version=2"><img src="https://s3.amazonaws.com/cla-project-logo-prod/cla-not-signed.svg" alt="CLA Not Signed" align="left" height="28" width="328"></a><br/><br /><ul><li><a href='https://api.easycla.lfx.linuxfoundation.org/v2/repository-provider/github/sign/12261526/38307428/4135/#/?version=2' target='_blank'>:x:</a> - login: @Heyitsquoracom / name: [email protected] . The commit (b6081f914f0c5c22ee48d26aff4b473bf17627ce) is not authorized under a signed CLA. <a href='https://api.easycla.lfx.linuxfoundation.org/v2/repository-provider/github/sign/12261526/38307428/4135/#/?version=2' target='_blank'>Please click here to be authorized</a>. For further assistance with EasyCLA, <a href='https://jira.linuxfoundation.org/servicedesk/customer/portal/4' target='_blank'>please submit a support request ticket</a>.</li></ul><!-- Date Modified: 2024-06-28 04:40:51.630768 -->
- Error with version v16.9.0: `Can't resolve '@apollo/subgraph/dist/directives''` HOT 1
- Type is incorrect in graphql ExecutionResult with new type GraphQLFormattedError 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-js.