Calling third-party API from Cloudflare Workers by using Fetch API

Sometimes, we want to use external (third-party) API, like OpenAI, from Cloudflare Workers. But some SDK canno […]

広告ここから
広告ここまで

目次

    Sometimes, we want to use external (third-party) API, like OpenAI, from Cloudflare Workers.

    But some SDK cannot use their SDK because of the Workers specification.

    Making original SDK client class by using Fetch API

    For instance, we can use Fetch API to call these APIs instead of their SDK.

    In this example, we call OpenAI API using fetch through the custom fetcher class.

    export class OpenAI {
        private readonly apiURL = "https://api.openai.com"
        private readonly apiVersion = "v1"
        private readonly headers: HeadersInit = {}
    
        public constructor(apiKey: string) {
            this.headers = {
                "Authorization": `Bearer ${apiKey}`,
                "Content-Type": "application/json"
            }
        }
    
        private _createOpenAPIRequestURL(path: string) {
            const paths = `${this.apiVersion}/${path}`.replace(////, "/")
            return `${this.apiURL}/${paths}`
        }
    
        private async _fetch(input: RequestInfo, init: RequestInit) {
            init.headers = {
                ...this.headers,
                ...this.headers,
            }
            const response = await fetch(input, init)
            return response.json()
        }
    }

    If you want to use TypeScript, you can import the type definitions from their SDK.

    import { CreateChatCompletionRequest, CreateChatCompletionResponse } from "openai";
    
    
    export class OpenAI {
        private readonly apiURL = "https://api.openai.com"
        private readonly apiVersion = "v1"
        private readonly headers: HeadersInit = {}
    
        public constructor(apiKey: string) {
            this.headers = {
                "Authorization": `Bearer ${apiKey}`,
                "Content-Type": "application/json"
            }
        }
    
        private _createOpenAPIRequestURL(path: string) {
            const paths = `${this.apiVersion}/${path}`.replace(////, "/")
            return `${this.apiURL}/${paths}`
        }
    
        private async _fetch(input: RequestInfo, init: RequestInit) {
            init.headers = {
                ...this.headers,
                ...this.headers,
            }
            const response = await fetch(input, init)
            return response.json()
        }
    
        public async createChatCompletion(body: CreateChatCompletionRequest): Promise<CreateChatCompletionResponse> {
            const result = await this._fetch(this._createOpenAPIRequestURL('chat/completions'), {
                method: "POST",
                body: JSON.stringify(body)
            })
            return result as CreateChatCompletionResponse
        }
    }

    Reusable fetcher client

    When you want to use several external API from Cloudflare Workers, you can reuse this fetch client by creating a new abstract class like this:

    import { CreateChatCompletionRequest, CreateChatCompletionResponse } from "openai";
    
    
    export abstract class FetchCLient {
        protected readonly baseURL: string
        protected readonly headers: HeadersInit = {}
    
        public constructor(baseURL: string, apiKey: string) {
            this.baseURL = baseURL
            this.headers = {
                "Authorization": `Bearer ${apiKey}`,
                "Content-Type": "application/json"
            }
        }
    
        protected async _fetch<R = unknown>(input: RequestInfo, init: RequestInit): Promise<R> {
            init.headers = {
                ...this.headers,
                ...this.headers,
            }
            const response = await fetch(input, init)
            return response.json()
        }
    }
    

    And you can extend this class for the external API.

    
    export class OpenAI extends FetchCLient {
        public constructor(apiKey: string) {
            super("https://api.openai.com/v1", apiKey)
        }
        public async createChatCompletion(body: CreateChatCompletionRequest): Promise<CreateChatCompletionResponse> {
            const result = await this._fetch<CreateChatCompletionResponse>(`${this.baseURL}/chat/completions`, {
                method: "POST",
                body: JSON.stringify(body)
            })
            return result
        }
    
    }

    広告ここから
    広告ここまで

    Random posts

    Home
    Search
    Bookmark