Skip to content

cuppachino/openapi-typescript-fetch

 
 

Repository files navigation

📘️ @cuppachino/openapi-fetch

Changes from upstream

  • ✅ Fixed ESM/CJS support for browsers and node.
  • ✅ Zero-parameter requests do not require an empty object argument.

version(scoped)

A typed fetch client for openapi-typescript

Installation

pnpm add @cuppachino/openapi-fetch
npm i @cuppachino/openapi-fetch
yarn add @cuppachino/openapi-fetch

Features

Supports JSON request and responses

Usage

Generate typescript definition from schema

npx openapi-typescript https://petstore.swagger.io/v2/swagger.json --output petstore.ts # 🔭 Loading spec from https://petstore.swagger.io/v2/swagger.json… # 🚀 https://petstore.swagger.io/v2/swagger.json -> petstore.ts [650ms]

Typed fetch client

import 'whatwg-fetch' import { Fetcher } from '@cuppachino/openapi-fetch' import { paths } from './petstore' // declare fetcher for paths const fetcher = Fetcher.for<paths>() // global configuration fetcher.configure({ baseUrl: 'https://petstore.swagger.io/v2', init: { headers: { ... }, }, use: [...] // middlewares }) // create fetch operations const findPetsByStatus = fetcher.path('/pet/findByStatus').method('get').create() const addPet = fetcher.path('/pet').method('post').create() // fetch const { status, data: pets } = await findPetsByStatus({ status: ['available', 'pending'], }) console.log(pets[0])

Typed Error Handling

A non-ok fetch response throws a generic ApiError

But an Openapi document can declare a different response type for each status code, or a default error response type

These can be accessed via a discriminated union on status, as in code snippet below

const findPetsByStatus = fetcher.path('/pet/findByStatus').method('get').create() const addPet = fetcher.path('/pet').method('post').create() try { await findPetsByStatus({ ... }) await addPet({ ... }) } catch(e) { // check which operation threw the exception if (e instanceof addPet.Error) { // get discriminated union { status, data }  const error = e.getActualType() if (error.status === 400) { error.data.validationErrors // only available for a 400 response } else if (error.status === 500) { error.data.errorMessage // only available for a 500 response } else { ... } } }

Middleware

Middlewares can be used to pre and post process fetch operations (log api calls, add auth headers etc)

import { Middleware } from '@cuppachino/openapi-fetch' const logger: Middleware = async (url, init, next) => { console.log(`fetching ${url}`) const response = await next(url, init) console.log(`fetched ${url}`) return response } fetcher.configure({ baseUrl: 'https://petstore.swagger.io/v2', init: { ... }, use: [logger], }) // or fetcher.use(logger)

Server Side Usage

This library can be used server side with node-fetch

Node CommonJS setup

// install node-fetch v2 npm install node-fetch@2 npm install @types/node-fetch@2 // fetch-polyfill.ts import fetch, { Headers, Request, Response } from 'node-fetch' if (!globalThis.fetch) { globalThis.fetch = fetch as any globalThis.Headers = Headers as any globalThis.Request = Request as any globalThis.Response = Response as any } // index.ts import './fetch-polyfill'

Utility Types

  • OpArgType - Infer argument type of an operation
  • OpReturnType - Infer return type of an operation
  • OpErrorType - Infer error type of an operation
  • FetchArgType - Argument type of a typed fetch operation
  • FetchReturnType - Return type of a typed fetch operation
  • FetchErrorType - Error type of a typed fetch operation
  • TypedFetch - Fetch operation type
import { paths, operations } from './petstore' type Arg = OpArgType<operations['findPetsByStatus']> type Ret = OpReturnType<operations['findPetsByStatus']> type Err = OpErrorType<operations['findPetsByStatus']> type Arg = OpArgType<paths['/pet/findByStatus']['get']> type Ret = OpReturnType<paths['/pet/findByStatus']['get']> type Err = OpErrorType<paths['/pet/findByStatus']['get']> type FindPetsByStatus = TypedFetch<operations['findPetsByStatus']> const findPetsByStatus = fetcher.path('/pet/findByStatus').method('get').create() type Arg = FetchArgType<typeof findPetsByStatus> type Ret = FetchReturnType<typeof findPetsByStatus> type Err = FetchErrorType<typeof findPetsByStatus>

Utility Methods

  • arrayRequestBody - Helper to merge params when request body is an array see issue
const body = arrayRequestBody([{ item: 1}], { param: 2}) // body type is { item: number }[] & { param: number }

Happy fetching! 👍

About

Fetch builder for openapi-typescript. (Forked with updates from ajaishankar/openapi-typescript-fetch

Topics

Resources

License

Stars

Watchers

Forks

Languages

  • TypeScript 99.9%
  • JavaScript 0.1%