I thought I understood API development, but GraphQL and TypeScript have made me a better API developer.

Learning Outcomes

Here are some of the outcomes you can expect from learning TypeScript and GraphQL. I’ve tried to emphasize concepts that I consider beyond REST and traditional JavaScript.

Develop a strong understanding of APIs

I’ve been developing APIs (Application Programming Interfaces) since before REST. I’ve seen a few different approaches come and go, there were other specifications like SOAP (XML), CORBA, and Hateoas. I’ve worked on hundreds of REST endpoints. I thought I understood API development, but GraphQL and TypeScript have made me a better API developer.

GraphQL API’s are intrinsically introspective. You can get a fully-typed schema of all the data available, making it self-documenting. This allows you to develop strong intuition about APIs, and enhance your consciousness of data types, entities, and abstractions.

You aren’t overloading endpoints, you’re not over-fetching or under-fetching. You’re not jumping around different tech stacks, subscriptions are in the same shape as queries (based on JSON), mutations are also the same shape except by denoting it a ‘mutation’ you’re explicitly stating the query can have side effects. It is more readable by humans and machines.

REST lacked proper standards so no industry standardization gained favor, there were too many flavors, too many signatures and documentation went out of date quickly. With GraphQL you learn best practices from industry veterans who are committed to adopting a standard approach and rolling that out across the industry, standards allow common tooling because systems share a common interface.

There are tools like Swagger for REST that provide similar API introspection, but with GraphQL that process is automatic. The tool Swagger-to-GraphQL converts your existing Swagger schema to an executable GraphQL schema.

These tools combined give you the ability to construct powerful and practical programming interfaces that can be used by all GraphQL consumers.

TypeScript extends this concept by following through with type checks from the GraphQL API boundaries. It’s much harder to misuse an endpoint when it is fully typed. It encourages you to make better abstractions for your data and design your UI properly to accommodate that data.

Develop an understanding of type safety, and how that conveys a programmer’s true intentions

Type annotations give you a stronger sense of a programmer’s intentions. The opportunity to have end-to-end typing should be a huge motivating factor for anyone considering TypeScript+GraphQL.

In a modern web development stack, the power of typing can be experienced at multiple levels. Types allow your IDE to be smarter, suggesting the correct types as you develop. It can enhance your developer experience tremendously.

If you’re using a modern IDE like VS Code, TypeScript has strong guidelines and typed guard rails as you develop. Type errors are a huge source of bugs in JavaScript, and typing properly tends to improve your code quality.

It’s far better to identify a bug during development than to have a client discover it in production.

TypeScript at the language level combined with GraphQL at the API boundaries offers a high level of code introspection and safety. Type definitions make you a better developer.

Code generation offers the cherry on the cake. There are different packages available but most offer type generation for your client, which means you can get type definitions generated from your GraphQL API for your client code.

Since you are creating a typed data graph, you can generate TypeScript types for free.

You can even generate things like React components and GraphQL client hooks!

TypeScript enhances productivity and reduces insanity, it increases in value over time.

Analyze your code base with an integrated development environment (code completion, IntelliSense)

Intrinsic API introspection is significant because you’re effectively getting [some] documentation and run-time type checking for free. It’s far harder to make a mistake. Often you can autocomplete with just a ctrl-space key sequence, and things like field deprecations are presented in real-time. Most servers provide integrated API explorers like GraphQL Playground or GraphiQL.

VS Code features IntelliSense, it is a code-completion aid. It helps you learn more about the code you’re using. It keeps track of parameters as you’re typing, and add calls to properties and methods with only a few keystrokes. IntelliSense gets smarter with updates and is more intelligent when you provide good type definitions. There are tools for GraphQL that can automatically generate type definitions.

Generate code automatically

You should use a code generator to auto-generate your types from your GraphQL API, but you can also generate other things like hooks for React and Apollo. You can even write your own plugins to generate your own code, don’t forget you have access to static type definitions and schema introspection.

There are different generators to try: I recommend GraphQL Code Generator, but there is also TypeGraphQL, and Apollo tools provides Apollo code-gen.

Imagine the future of code generation. It’s not hard to envision integrated components generated as templates, but what about entire client applications! With machine learning, this seems highly probable.

Identify bugs earlier with compile-time safety and static typing

If you change something, you’ll immediately see errors and warnings, Anything that is broken will be highlighted. You get contract validation across features, this produces extremely clean code because basic errors are much harder to make and breaking changes are immediately apparent.

Validate and comply with contracts across features/teams

Consider how code generation can create type definitions from a GraphQL API and how GraphQL facilitates bringing together different data sources into a single data graph. Micro-services are easier to manage.

Several frameworks have working implementations of “schema stitching” also known as “federation” (Apollo) or “remote schema” (Hasura). There is still some work to be done on things like scaling and subscriptions, but these tools effectively bring multiple graphs from different silos into a single concise data graph.

With TypeScript type definitions and GraphQL APIs, it’s possible to have end-to-end contract validation across features. This is very powerful, if a team breaks an integration the error be detected at compile-time and your continuous integration environment (CI) can be configured to do compile-time checks across the remote schema.

This is an exciting concept because you can imagine how this could evolve across the entire web. Consider ES modules developed by different groups.

Access new features before they are available to JavaScript

TypeScript supports everything in ECMAScript 2015 and adds an additional set of features:

In addition to these special TypeScript features, there are also future ECMAScript features that would only normally be available if you used something like Babel plugins. TypeScript includes popular ES next features like:

Don’t forget TypeScript compiles down to regular ECMAScript so these features should work with today's JavaScript containers (browser, Node.js etc).

Understand the impact of code changes

Schema change validation can be implemented as part of your build process. Apollo Graph Manager can even validate server schema changes against clients. There is a GitHub integration where you can monitor client requests, if there are clients requesting a deprecated field on the data graph, you can trace them, or remove them when they’re no longer in use.

TypeScript can measure impact almost immediately, it won’t even transpile if there are errors. If your regular CI workflow just runs test or build, TypeScript will do a compile-time check. If you are running code-gen against your API’s this will flag a problem even it’s on the other side of the organization.

Apply principled decisions to standardized application development

It’s subjective, but having an opinion is generally a good thing. It’s a mistake to approach GraphQL with first principles. You should follow best practices wherever possible and actively seek out opinions and opinionated software. Jump on an existing open-source implementation if you need to extend it.

Principled GraphQL, written by Geoff Schmidt and Matt DeBergalis of the Apollo team is a guide inspired by The Twelve-Factor App (another great best practices guide you should read). It’s a really good starting point for understanding how to approach your GraphQL application with experience from the field.

The cool thing about opinionated software is that you don’t have to waste your time formulating your own opinion and arguing about it with your colleagues, often solutions for your problem have already been considered.

Prettier is one of my favorite open-source projects, it’s a fantastic example of opinionated software, it aims to stop all on-going debates about code formatting by accepting a common style guide.

Develop applications with common tooling

GraphQL + TypeScript offers introspection of your entire code base, a GraphQL introspection schema can be used to drive many applications.

There are entire frameworks that are built around GraphQL introspection. Consider tools like Apollo Client, it builds a comprehensive normalized data cache in the browser which can be queried directly or incorporated into a local link state for local state management.

There are GraphQL API explorers like GraphQL Playground or GraphiQL. There are graph visualizers like GraphQL Voyager, design tools like GraphQL Editor, headless content management tools like GraphCMS. New tools are being released daily.