5 ms·
We have been using GraphQL for almost a year now and I'm really pleased with it. In my mind it both solves the type issue, while also providing great flexibilit
by filleokus 9y ago
We have been using GraphQL for almost a year now and I'm really pleased with it. In my mind it both solves the type issue, while also providing great flexibility in what data to fetch. I guess this could be used to improve an existing REST API without the big cost of moving to GraphQL (which might even be impossible sometimes).
Maybe there are also some situations where GraphQL fails, I would definitely be interested to hear about that.
- WorldMaker 9y agoOne of my complaints with GraphQL (as an observer; I've not yet directly worked with GraphQL) is that while it has a bunch of type information, most of that is fairly opaque to Typescript itself: queries themselves are mostly opaque strings, and most examples I've seen of query usage (and this may be mostly just a problem with wild examples as opposed to real usage) most of them just use the result of a query call as any-typed, manual type assertion, or manual generic argument to the query call. It seems to me that all of GraphQL's type information should be easier to use in Typescript. I have noticed there is a compiler of .graphql files to .d.ts files [1], and I could see using something like that the way that RESTyped is used in the article here (though it's "backwards" from the RESTyped model where the Typescript definitions are the source of truth [2]), but at least in examples I've seen to date of GraphQL in the wild it does seem like there is a similar need in the GraphQL world for something like RESTyped. [1] https://www.npmjs.com/package/graphql-typescript-definitions https://www.npmjs.com/package/graphql-typescript-definitions [2] Which leads me to wondering if it would be nice to have a Typescript Definition file to GraphQL compiler.
- lewisl9029 9y agoIf you use Apollo as your GraphQL client, there's apollo-codegen [0], which supports generating both Flow and TypeScript type definitions. Relay Modern's query compiler also generates Flow types AFAIK. But that's only for the client side. I suppose if you'd like to use typed JavaScript on the server side, something like the library you've posted might be your best bet, since client side solutions like apollo-codegen generate types based on the exact set of queries in your client-side app, which might not be all that useful for implementing the GraphQL server itself (unless maybe your API is private and you can afford to implement some form of persisted queries?). Having access to all the individual base types specified in your schema would probably be more useful for that purpose. [0] https://github.com/apollographql/apollo-codegen https://github.com/apollographql/apollo-codegen
- WorldMaker 9y agoYes, that's the big thing I've been seeing: it's definitely the server-side story that seems somewhat deficient right now, in terms of end-to-end types. It does seem like a server built with Typescript should be able to save a lot of manual GraphQL writing work and reuse a bunch of Typescript type information, but I don't feel like I've seen a lot of examples and/or libraries of people doing that.
- crucialfelix 9y agoYes, it's really important to have the frontend types generated directly from what the backend generated graphql schema specifies. We shouldn't have to type anything at all. I wrote an article about using apollo-codegen to generate all the Typescript types: https://medium.com/@crucialfelix/bridging-the-server-client-gap-graphql-typescript-and-apollo-codegen-e5b54fa96ae2 https://medium.com/@crucialfelix/bridging-the-server-client-... It's still a few steps too many, but it's getting there. I'm about to write up the second article which deals with mutations. This lets me import only one type: import { SetAptListOnWebProps } from "../mutations"; and then this.props.mutate is fully typed: (property) mutate: (options: MutationOptions<{ apt: string; listOnWeb: boolean; }, { setAptListOnWeb: { apt: { id: string; listOnWeb: boolean; __typename: "Apt"; }; __typename: "SetAptListOnWebPayload"; }; }>) => Promise<{ data: { setAptListOnWeb: { apt: { id: string; listOnWeb: boolean; __typename: "Apt"; }; __typename: "SetAptListOnWebPayload"; }; }; errors?: GraphQLError[]; loading: boolean; networkStatus: NetworkStatus; stale: boolean; }> First type argument is the mutation input variables, the optional second is the shape of the optimistic response.
- whatever_dude 9y agoI've been using something similar and it solves many problems elegantly. You use a build step to connect to the server and run an introspection query to get all server types ran generated dynamically as .ts files (or .js for flow). Then your code has access to your data model with very little to maintain: a dev can change the backend model in the server and you'll know right away. You almost don't need documentation, since the schema can also contain comments. If anything, a GraphQL server can still be used in a RESTful manner (perform a pre-written query, get its results) so there's a lot of pros (with very, if any, cons) with using a GraphQL server.
- kodablah 9y ago> Maybe there are also some situations where GraphQL fails, I would definitely be interested to hear about that. I know one, but it will take you a while to realize it. Allowing a lot of flexibility in query types makes it harder to optimize later when you can't predict the code paths your clients will take. In the API world, I have learned the hard way that flexibility is a bad thing especially compared to specific ways to obtain data and very optimizable, well-known "hot" paths to data.
- foota 9y agoYou can always use analytics on the calls made to find hot code paths.
- kodablah 9y agoThis misses the point. I'm not talking about finding hot paths, I'm talking about limiting the total predictable path count so you can optimize better. Or, as I often saw, when you have so many paths to different data pieces, you don't test every permutation of every combination of paths, and a caller finds one that hurts for some reason (e.g. bad optimization choice by your RDBMS).
- foota 9y agoYes, but with analytics in place you'll find that when it happens and be able to fix it?