Strongly type third-party integrations with TypeScript

Markus Tacker

Markus Tacker

Pronouns: he/him

Principal R&D Engineer
Nordic Semiconductor
Trondheim, Norway

coderbyheart.com/socials

Needs

  • Validate incoming data
  • Validate outgoing data
  • TypeScript
  • Third-party endpoint (we cannot use gRPC/tRPC)

Why JSON schema

  • Good enough
  • Widely known syntax for defining validations
  • Can easily be ported to other implementations
  • Can be adopted / read by other teams using other languages

Solution: @sinclair/typebox

  • JSON Schema based
  • In-memory validation
  • Fast TypeCompiler (~2x faster than AJV)

Validation basics

Code demo: code/validator/validateWithTypeBox.ts

Best practices

  • Re-use and compose
  • Add titles, descriptions
  • Keep schema open (allow additional properties)

Validation of third-party API requests

const maybeCellGeolocation = await c.post({
  resource: "location/ground-fix",
  payload,
  requestSchema: groundFixRequestSchema,
  responseSchema: locateResultSchema,
});
if ("error" in maybeCellGeolocation) {
  return { located: false };
}
const { lat, lng, uncertainty } = maybeCellGeolocation;
return { lat, lng, accuracy: uncertainty, located: true };

location service request

validatingFetch() for JSX

  • handle async validation
  • nicer syntax

source on GitHub

Code demo: code/preact/SIMUsageHistory.tsx

Code organization

Input / Output validation

import {
  validateInput,
  type ValidInput,
} from "@hello.nrfcloud.com/lambda-helpers/validateInput";
import { validateResponse } from "@hello.nrfcloud.com/lambda-helpers/validateResponse";
import middy from "@middy/core";
import { Type } from "@sinclair/typebox";
import type { Context } from "aws-lambda";

const InputSchema = Type.Object({});

export const handler = middy()
  .use(validateInput(InputSchema))
  .use(validateResponse(Type.Object({})))
  .handler(async (_, context: ValidInput<typeof InputSchema> & Context) => {
    // ...
  });

example: validateInput · validateResponse

Summary

  • Create validation for all your API requests and responses.
  • JSON schema is mostly good enough and well understood.
  • Get (monitoring) alerts about breaking API changes immediately.
  • Eliminate mistakes when creating test data.

Discussion

Alternatives?

Thank you

Please share your feedback!

coderbyheart.com/socials

Latest version:
coderbyheart.com/talks