24-Dec

JavaScript

Get typesafe APIs with Zod and ChatGPT

Want typesafe APIs, but don't feel like writing them yourself? I have a trick up my sleeve I want to share.

3 min read

·

By Kristofer Giltvedt Selbekk

·

December 24, 2023

Since I finally got on board with TypeScript a couple of years ago, I've gotten spoiled with the luxury of type safety. You get auto completion, no "cannot read property of undefined" errors, and just a nicer development experience.

When integrating with new systems, a lot of services provide you with a typesafe SDK that makes it easy to get end-to-end type safe code even with your integration points. It's such a nice experience! However, not all services have gotten that far in their development experience backlog yet.

Luckily, all hope is not lost. In this quick tip of an article, I will show you how you can get typesafe integrations in a couple of minute's work.

Meet zod

Hi Zod. If you haven't met Zod yet, Zod is a type safe schema library that lets you put together incredibly complex validation schemas, and parse data through it. Once the data is parsed, you're guaranteed to either have validated typesafe data, or an error telling you what went wrong.

Although Zod is a versatile library with a bunch of ways you can use it, form and input validation of course, but my favorite thing to use it for is to parse responses from APIs. This way, I can verify that the API response is indeed what it says it is, and if the API changes, I will know in the API layer, and not because I'm getting an error deep in my business logic due to a missing value. This concept is called JSON decoders, and was popularized by Elm back in the days.

The code would look something like this:

import { z } from "zod";

const postSchema = z.object({
  title: z.string(),
  published: z.string().datetime(),
  authors: z.array(
    z.object({ name: z.string() })
  ),
  body: z.string()
})

const getPosts = async () => {
  const response = await fetch('/api/posts');
  const json = await response.json();
  return postSchema.parse(json); // <- typesafe!
}

Being a bit lazy

Now, most API responses from external services typically aren't like this. They look more like this:

{"items":{"total_count":"1","item":[{"newsdeskML":"2.1","type_of_media":"pressrelease","language":"no","source_id":"123","source_name":"Some company","pressroom_name":"Some company 1","pressroom":"no","pressroom_id":"123","organization_number":"984 661 177","id":"3294494","url":"https://www.mynewsdesk.com/no/123/pressreleases/3294494","published_at":"2023-10-17 08:58:00","created_at":"2023-12-21 10:08:20","updated_at":"2023-12-21 10:13:59","header":"Some title","summary":"Summary.","body":"<redacted>","boilerplate":null,"image_caption":"","image":"https://resources.mynewsdesk.com/image/upload/c_fill,dpr_auto,f_auto,g_auto,q_auto:good,w_1782/todtxagcwrl177vykzyc","image_small":"https://resources.mynewsdesk.com/image/upload/c_fill,dpr_auto,f_auto,g_auto,q_auto:good,w_746/todtxagcwrl177vykzyc","image_medium":"https://resources.mynewsdesk.com/image/upload/c_fill,dpr_auto,f_auto,g_auto,q_auto:good,w_746/todtxagcwrl177vykzyc","image_thumbnail_large":"https://resources.mynewsdesk.com/image/upload/c_fill,dpr_auto,f_auto,g_auto,h_500,q_auto:good,w_500/todtxagcwrl177vykzyc","image_thumbnail_medium":"https://resources.mynewsdesk.com/image/upload/c_fill,dpr_auto,f_auto,g_auto,h_250,q_auto:good,w_250/todtxagcwrl177vykzyc","image_thumbnail_small":"https://resources.mynewsdesk.com/image/upload/c_fill,dpr_auto,f_auto,g_auto,h_250,q_auto:good,w_250/todtxagcwrl177vykzyc","tags":{"tag":"Ruteendring"},"contact_people":"\n  ","related_items":{"related_item":{"item_id":"2932194","type_of_media":"image"}}}]}}

Shivvers. Writing this stuff up like a zod schema is going to be tedious and error prone work, and you're going not going to have the best day at work.

Luckily, this is right up the alley for your favorite generative AI assistant! Just copy and paste this booger of a response into your GPT of choice, and tell it to create a zod schema for it. Chat GPT gladly did the task in about 10 seconds:

A screenshot of what ChatGPT returned – a complete zod schema

Copy and paste that code into your own codebase (preferably its own file, if it's as big as this), verify that there aren't any places you can improve the schema, and go on with your day.

Thanks for coming to my Ted talk.