Partners

The DatoCMS Blog

Get the best TypeScript DX: introducing "Strict Mode" for GraphQL CDA

Posted on June 23rd, 2022 by Stefano Verna

TL;DR. We're happy to announce an addition to our GraphQL Content Delivery API offering. With the new Strict Mode, you can obtain more accurate and reliable TypeScript types, greatly simplifying the code to be written on the frontend side!

The backstory

If you have ever worked in TypeScript, you are familiar with the feeling of peace of mind and security that working with defined types brings. Less doubt and uncertainty, faster development cycles, less context switching between the code editor and browser.

There is a problem, however: when your app interfaces with the outside world โ€” for example, when you fetch data from a headless CMS โ€” who should write the types of the responses you receive? And how? ๐Ÿ˜•

Well, when you work with a GraphQL API, you definitely have an advantage. Since every GraphQL endpoint offers a complete typed definition of every query available, there are tools called "code generators" that can automatically build TypeScript types for you.

Some of the most popular GraphQL code generators for TypeScript are Apollo Codegen, GraphQL Code Generator or genql, but there are similar tools for other languages too. If you're working in Java, for example, the DGS Framework by Netflix can generate a fully-typed GraphQL client.

If you've ever tried any of those tools, you know they really feel like magic: you can instantly work 100 times better and โ€” even better โ€” at no extra cost, as all the dirty work is handled by a library ๐Ÿ˜Ž.

There's only one thing that can transform a potentially ideal solution like this one, into a total nightmare for developers. And that is when the GraphQL API offers a poorly-typed schema.

If that's the case, the resulting TypeScript types will be too broad, and you'll be forced to either cover a lot of useless edge cases in your code base, or fill your code with ?. (optional-chaining) and ! (non-null assertions), which are both considered harmful operators.

Unfortunately... that's exactly the case with most of the headless CMSs ๐Ÿ˜ช. Very few CMSs have a rigid validation system that can 100% guarantee a format for returned values. So all they can do is offer GraphQL types with the same few guarantees โ€” ie. "maybe the title is present and it's a string, but maybe it's just null, can't tell for sure".

Of course, the fact that they cannot offer rigid validations is a much broader problem. It just happens to become far more visible when you're working in a typed language with code generators as a glue.

But wait, DatoCMS has a rigid validation system! So we can do better than this! ๐Ÿ’ก

Introducing the new Strict Mode

Starting from today, if you pass an additional X-Exclude-Invalid: true header to your Content Delivery API requests, you're asking to enter the new strict mode.

What does it do exactly? As the header name suggests, it only returns valid records. Invalid ones are automatically filtered out from GraphQL responses.

And what this change enables us to achieve? Super-strict GraphQL types! ๐Ÿ’ช

Example

Suppose your Article model has a title field with a "required" validation applied.

With strict-mode enabled, the resulting GraphQL type will be String!, as opposed to String which would be the regular GraphQL type without strict-mode. See that missing exclamation mark at the end? In GraphQL that means "the title is 100% a string, no way it will ever be null".

And that changes everything.

The resulting TypeScript type produced by the code generators will be string, as opposed to string | null | undefined. That means you won't have to handle those additional cases in your frontend, and TypeScript won't complain if you simply write things like article.title.toLowerCase().

If you multiply this small improvement over every use of every field, of every model in your project... you can start grasping the level of improvement in DX you can get.

Read all the details in the docs!

Strict Mode not only reacts to validations of type "required" present in your fields, but it improves the GraphQL schema in many other scenarios, for example image and video management. You can read all the details in our documentation.

In the following weeks we'll release a new Next.js + TypeScript + GraphQL codegen tutorial complete with a Starter Project, to help you get started in no time with these awesome technologies.

Do you think there are other places where Strict Mode could help you deliver safer, better code? As always, don't hesitate letting us in our Community!