And this is an open source tool that will automatically generate TypeScript code from either a GraphQL schema or a GraphQL query operation. So we use Codegen on both the server and client side. On the server side, we use it to generate types for our GraphQL resolvers. And on the client, we use it to generate the React query client from our GraphQL queries.
I'll provide a few examples on the differences between how we use it on the server and client. Using Codegen itself is pretty easy. GraphQL Codegen provides a command line tool that is pretty easy to use. You just have to run GraphQL Codegen and give it a config.
So I just want to give an example of specifically how we're using GraphQL Codegen on the server. This is a code snippet taken from our code base. This represents the environment connection schema that is designed to represent a list of project environments. And using the code connection edge nomenclature is sometimes common in GraphQL when representing paginated lists of data. The resolver for this connection simply fetches from the project environments database and returns a list of environments.
One of the issues that we found with using TypeScript in GraphQL has been adding type safety to these resolver functions. For example, by default, arguments like limit after filter won't get types generated for them. So we have to manually add in types ourselves. So this is an example of a type that we explicitly defined for those resolver arguments. And GraphQL code gen provides a workaround for these issues. It allows you to explicitly add in configuration for overriding their internal generation. So for example, in this case, we are overriding the environment's connection generation using our explicitly defined types here. In the environment connections model, we mapped to the environment connection schema definition.
On the client side, you can use the command line tool the same way by simply calling GraphQL CodeGen. Code generation is a lot easier on the client. So given a GraphQL query such as this one, in this example we are fetching a list of environments from our GraphQL server. And we can generate a hook from that query using GraphQL CodeGen. So this hook will fetch the data that we need, and it will be completely type safe. So in this example, as you can see, when you call, or when you type in through your text editor query.results, you'll be able to see the various attributes that are on that object.
Some of the benefits that we've experienced migrating to this architecture have been debugging. So it's much easier to have the type checker catch any potential issues. Performance, there's various compile time optimizations that you can get from having your code base in TypeScript, and we have seen a performance boost in our application. In terms of navigating the code base, having those type annotations have made working with internal libraries a lot easier to use, especially libraries that don't have very good documentation. And an added benefit to using TypeScript has been it's improved our overall developer experience because it's allowed front-end and back-end developers to work in parallel without having to depend on each other.
Some of my closing thoughts are migrating a monolithic code base is challenging, but with the right architecture, even a small team can make it possible. So we benefited a lot from setting up those internal endpoints and simply using GraphQL as a proxy to our internal API. And overall TypeScript improved our ability to debug and optimize our code. That's all.
Comments