-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Support for Tuples #534
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Glad you found a workaround for it! Just to make sure I understood, instead of a tuple, you're doing: type MobiledocCard {
name: String!
payload: CardPayload!
}
# This is all the different kinds of cards:
union CardPayload = SomeCardPayload | AnotherCardPayload # | ... | ...
type SomeCardPayload {
# a concrete kind of card
}
type AnotherCardPayload {
# another concrete kind of card
} Then, you can query it like cards {
name
... on SomeCardPayload { ... }
... on AnotherCardPayload { ... }
} Is that right? Anyhow, it sounds like you found a nice way to provide meaningful names to that tuple! |
Yes, that's correct on how we're handling it. Unfortunately, querying it in this way does not give us valid mobiledoc since tuples are a core part of its datastructure. This results in us having to map over the graphql responses and convert the pojos back to valid mobiledoc. |
Tuple support is interesting. I think it's a less-generalized version of user-defined parameterized types. I could see parameterized types both adding a lot of value and adding a lot of pain for implementers, as well as confusion for people using them. If someone wants to champion tuple support, I'd encourage doing it in a way that in the future could also unlock parameterized types. Tuples could also be used to solve the Map-type question as well. I'm marking this as "needs champion", but whoever takes this on should also read through the map-types discussion at #101. I think they have a lot of problems and solution-spaces in common. |
Hey @mjmahone, As for the proposed change: Is a tuple a new type of Value? Or does it belong in the Do you have any suggestions on how to implement this in a way that would allow for parameterized types? As for the proposal: |
I want to give an example of the use case of tuple. I am building a project of which background is Math. We need query something like coordinate, size dimension.. |
Another use case: 3-tuples for representing conditions:
e.g. I see that frameworks like Prisma append the operator to the field name, like Something like Edit: And ordering:
|
This sounds like a case for not just tuples but associative arrays and multi dimensional arrays in general. That way you are not bound to just 2 values. |
@excitedbox Tuples are not limited to 2 elements. Or do you mean something else? |
I have a use case where we have several ranges which are optional, but cannot be unbounded if given. Essentially, This is not correctly satisfied by two columns, e.g. It could be semi-correctly represented as a nullable array of integers Latitude and longitude are a similar use case, which we are currently working around with two columns and jumping through a bunch of hoops. |
@rintaun for these cases, you can create a new type type MyType {
range: Range
}
type Range {
lowerBound: Int!
upperBound: Int!
} That way they can both be null by having |
A +1 for including tuples is for incorporating the GeoJSON IETF standard as a type where the Geometry part is specified in float arrays Instead of having to convert the nested arrays to objects, and then convert them back into arrays to maintain compatibility with the standard Full example:
Originally posted by @r0kk3rz in #423 (comment) |
+1 for supporting GeoJSON spec |
FWIW, I've been following along here for years specifically because I required the use of GeoJSON types. However, as the project progressed and I became more familiar with how to "think in GraphQL," I realized that from the GraphQL perspective these Accordingly, we created custom scalars with their own validation logic in the "serialization" steps, which are otherwise just passthrough/JSON operations:
|
I found the simplest way of tackling this was to add a JSON type and just put the GeoJSON into that. https://dev.to/trackmystories/how-to-geojson-with-apollo-graphql-server-27ij |
Maybe it will be useful for apollo-graphql users. I solved this problem by using scalar types. scalar Range Then I specified a resolver for it (it is not fully ready to use, but that explains the idea) import { GraphQLScalarType, Kind } from 'graphql';
import { UserInputError } from 'apollo-server-fastify';
export const rangeScalar = new GraphQLScalarType({
name: 'Range',
description: 'Range custom scalar type',
serialize(value: [number, number]) {
return value;
},
parseValue(value: [number, number]) {
if (!Array.isArray(value)) throw new UserInputError('Must be array')
if (value.length !== 2) throw new UserInputError('Must be [Int!, Int!]')
return value;
},
parseLiteral(ast) {
if (ast.kind === Kind.LIST) {
if (ast.values.length !== 2) throw new UserInputError('Range must be tuple [Int, Int]')
return ast.values.map(field => {
if (field.kind !== 'IntValue') throw new UserInputError('Range must be int, but received' + field.kind)
return Number(field.value)
});
}
return null;
},
}); Also I added type mapping in the code generator config for supporting generation of Typescript interfaces (but I think that it would be better to import exact typescript interface/type or some another approach for situation when you have ыщьу complex type) config:
scalars:
Range: "[number, number]" So now these types look like this export type Scalars = {
ID: string;
String: string;
Boolean: boolean;
Int: number;
Float: number;
Date: any;
JSON: object;
Range: [number, number];
};
export type GSomeType = {
someRange: Scalars['Range'];
}; As a result, now I can pass tuples like |
Hi @ArtemKislov, thanks for the Range scalar, this works great thanks!! |
Any news here? |
Uh oh!
There was an error while loading. Please reload this page.
I work with a datatype, mobiledoc cards, that's represented as a tuple of a string followed by an object. Currently, to make it work in graphql I need to denormalize it to an object, then normalize to a tuple, and so on back and forth between our backend and frontend. Ideally I'd like a way to represent that the data structure as a tuple.
I would like to be able to do the following
The text was updated successfully, but these errors were encountered: