6 ms·
Grats: A More Pleasant Way to Build TypeScript GraphQL Servers
- highmastdon 3y agoHow is this different from Pothos, type-graphql or typegql? This announcement post doesn’t really have much to show for. I’d expect some comparison with other products that are on the market already
- pixelready 3y agoAnother one I saw recently that looks really promising in this vein is gql.tada, which provides some very nice LSP support. Anything in the TS space endorsed by Matt Pocock immediately gets my attention!
- captbaritone 3y agogql.tada is indeed very impressive and I think shares many of the same values as Grats. That said, I believe that today they only support the client path. Editor features and type generation for queries/mutations and fragments, although they do have interest in having a server story as well: https://github.com/0no-co/gql.tada/issues/10 https://github.com/0no-co/gql.tada/issues/10
- pixelready 3y agoThanks for clarifying and may I say it warms my heart to see the spirit of open, enthusiastic cross-project collaboration represented in that issue thread.
- captbaritone 3y agoGrats author here. It's spiritually similar to type-graphql or typegql, except that it's able to see the TypeSCript types as well as the class/method names. So, there's less duplication, less overhead, and a less confusing API (specifying argument types and return in type-graphql for example is pretty confusing. Unlike Pothos, this implementation-first approach is able to leverage simple type script names and types, whereas Pothos requires you to explicitly define all the names and types using their builder-pattern-for-graphql-SDL API. More here on why Grats does not use decorators like type-graphql: https://grats.capt.dev/docs/faq/why-use-comments/ https://grats.capt.dev/docs/faq/why-use-comments/
- Exoristos 3y agoDo you know what's an easy, pleasant way to write GraphQL? Just write the GraphQL, in a foo.graphql file.
- captbaritone 3y agoThis approach works fine for simple projects, but you also need to provide an implementation, and the two need to line up. This is what leads people to want solutions that either generate implementation types from the .graphql schema or (as Grats does) generate the .graphql schema from the implementation.
- Exoristos 3y agoYou just point graphql-codegen[0] at your GraphQL. 0 - https://the-guild.dev/graphql/codegen https://the-guild.dev/graphql/codegen
- Mustachio 3y agoI'm honestly not sold on using comment blocks as a way of adding such annotations. IMO the use of decorators is more pleasant and flexible.
- joegibbs 3y agoI don't think they'd work with TypeScript types because the types aren't actually retained in the compiled JavaScript but I agree. It seems kind of like a hack - usually you assume that comments aren't going to be executed or affect anything when the code is run, so it doesn't feel right when you use them to generate code.
- chatmasta 3y agoThe docs have a page [0] addressing this question. The tl;dr is because grats uses the TypeScript compiler to parse an AST, and the compiler already recognizes docblocks and attaches them to AST nodes. [0] https://grats.capt.dev/docs/faq/why-use-comments https://grats.capt.dev/docs/faq/why-use-comments
- captbaritone 3y agoGrats author here. I agree, decorators would be preferable. However, decorators are a runtime construct and as such cannot be applied to type constructs. This means you can’t, for example, annotate an interface definition, or add a description to an argument (since arguments are declared using an object type literal). You can read more about how I ended up settling on docblocks here: https://grats.capt.dev/docs/faq/why-use-comments https://grats.capt.dev/docs/faq/why-use-comments
- dventimihasura 3y agoThis is great, and I mean no disrespect, but aren't most servers written in anything but TypeScript? Java, Python, Ruby, .Net, Go, etc.? I recognize that changing it from "most servers" to "most GraphQL servers" brings in TypeScript, but I think that underscores the point I'm trying to make. Most HTTP APIs are REST (I think...that's worth checking) and will use something like Spring Boot, MuleSoft, Django, RoR, etc. In "enterprise" it's mostly going to be Java with Spring Boot or MuleSoft, or .Net. To have more GraphQL APIs, that's where the big game is: converting those REST APIs to GraphQL, or at least gradually (or not so gradually) persuading enterprises to switch from REST to GraphQL. With Spring Boot and MuleSoft, there's already a relatively easy story there: Spring GraphQL, Netflix DGS, MuleSoft Datagraph, graphql-java, etc.. There's probably something similar in the other ecosystems (Python, .Net, Ruby, etc.) You get to keep most of your code and development practices, but you do add in a few new libraries and you do write your code a little differently. So I just struggle to see what the audience is for TypeScript servers. Just my two cents.
- wubrr 3y agoThere are maaaany backends written in JavaScript (nodejs), TypeScript is a much better alternative, and this is a step in the right direction (though I'm personally not a fan of GraphQL).
- dventimihasura 3y ago> There are maaaany backends written in JavaScript (nodejs) Are there? I honestly don't know. I feel like it depends on how you count them. Are there JS/TS/nodejs "Backends For Frontends" (BFFs)? Yeah, I could see that, but then in that case there's at least as many other backends behind them, probably written in something else. Are there JS/TS/nodejs backends, mediating interaction with upstream databases in large enterprise organizations? I highly doubt it.
- calmoo 3y agoYes, node/TS backend APIs are extremely common.
- Yaina 3y agoI think this is a cool tool, although my personal preference when working with GraphQL is to have it be a very thin layer over my graphQL agnostic API function calls.
- captbaritone 3y agoGrats author here. That's supported as well. You can simply write annotated wrapper functions/classes/types/interfaces around your GraphQL agnostic API.
- sikan_ 3y agoMy team has been using this in production for the past 6 months - this is the best way to write Graphql server in Typescript by far and I have tried it all
- firecall 3y agoRemoved
- chatmasta 3y agoI've spent a lot of time with GraphQL, in the backend, frontend, and middleware, with TypeScript and also Python. At my startup, we used Strawberry on the backend, TypeScript in the middleware for stitching multiple APIs together [0], and codegen on the frontend with graphql-code-generator. Once we got it working, this was an amazing setup and my favorite part of our stack. GraphQL was a shared cross-language type layer with end-to-end auto-generation. We could define a resolver with Strawberry in Python, and get auto-generated types all the way to the frontend. We could collaborate on new features by defining a GraphQL schema in the RFC and coding the frontend and backend in parallel. I recognize a lot of the problems described here in the docs (the "How Grats Works" [1] page is a good read). I could see this library fulfilling a similar role to Strawberry, for a backend written in TypeScript rather than Python. Overall, it looks like a compelling implementation of some good ideas from the author, who incidentally is on the Relay team at Facebook, so he's probably done a lot of thinking in this problem space. Next time I'm working on a project with a TypeScript backend, I'll definitely take a look at this. [0] https://www.splitgraph.com/blog/graphql-schema-stitching https://www.splitgraph.com/blog/graphql-schema-stitching [1] https://grats.capt.dev/docs/faq/how-grats-works https://grats.capt.dev/docs/faq/how-grats-works
- emptysea 3y agoDid you manage to get IDE support to click into the backend implementation from the front end code?
- chatmasta 3y agoNo, that would have been cool though. We did have auto-generation on save of backend, all the way to the front. That was nice when it was just myself and co-founder, and I was doing a lot of fullstack code editing. But as we hired Python and TypeScript specialists, it became less important since each developer was only focused on their side. The interface, or "contract" between frontend and backend was the .graphql schema that we checked into the codebase. And if we needed to find an implementation, it was usually simple enough to grep for a matching resolver name.
- captbaritone 3y ago
- benpacker 3y agoI would choose Garph (Zod + 0 build step or client side codegen) over this (Typescript + two layers of codegen for client side type safety)
- ushakov 3y agoThat's the way!