astahmer / openapi-zod-client

Generate a zodios (typescript http client with zod validation) from an OpenAPI spec (json/yaml)

Home Page:openapi-zod-client.vercel.app

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

basePath should be configurable via environment variable

pkoo opened this issue · comments

tl;dr

As an operational guy
I would like to set the baseURL API parameter via environment variables
so that the developer does not have to build multiple API's for different server addresses.

Motivation

Within my company we are using lot's of different baseURL's for different environments (development, test, acceptance, reference & production).
All these environments have a different baseURL with the same OpenAPI spec.

And because I want only provide one container for all environments, I need a possibility to change the baseURL from "outside".

possible solutions

Currently I do have some possible solutions in my mind and would be glad to hear what you think about them.

  • integrate dotenv npm package
  • integrate config npm package
  • add new cli param to just export const endpoints & do not create a new Zodios(endpoints) instance in the generated file
  • leave it as it is and use the workaround described below

workaround

You can access the readonly api property of the generated Zodios instance and create an own Zodios instance where you can configure the baseURL.
But with this, we do have two Zodios Instances, which might confuse and let the developer import the "wrong" one.

src/generated/api.ts:

export const api = new Zodios(endpoints);

src/client/ApiClient.ts:

import { api } from '../generated/api';

const endpoints = api.api;
export const apiClient = new Zodios(process.env.API_BASE_PATH, endpoints);

hey, you could:

  • use the CLI option to change the base URL with your ENV var (if you generate the API client in your CI): -b, --base-url <url> Base url for the api
  • use the CLI option & pass a custom template that fits your needs: -t, --template <path> Template path for the handlebars template that will be used to generate the output

your custom template could look like this (I only changed the last line of the template.hbs file)

I do not want to create separate build commands/steps within my CI for each environment, because that would mean that I would have different containers to run on kubernetes.

The template option does the trick for me, exporting the endpoints makeApi result and not creating the Zodios instance within the generated api.

has there been any consideration for exporting a createApiClient function along with the current api export?

export const api = new Zodios(endpoints)

export function createApiClient(baseUrl: string) {
  return new Zodios(baseUrl, endpoints)
}

It seems overkill to create a completely custom template (or many builds), for what is a pretty standard requirement - almost everyone varies their API endpoint per environment. This would be useful for most consumers, and adds very little in terms of file size

no I didn't think about adding this, but I mean, why not
I'm neither for or against it tbh

but let's say we add this in the default template, maybe people will then make a custom template to remove either of these (export const api or export function createApi depending on people)

to me, the default template is more of a preconfigured showcase of what you can do, but everyone has its custom needs so imo everyone should make a custom template & pass it as (CLI or exported lib function) option

EDIT: still, if you really want it it's fine we can add it 😅

why would they want to remove them, outside of aesthetics? either of those would get tree-shaken away if unused.

i guess we have differing philosophies here :D i'd say the default should cover the 95% case, and a custom template should be the escape hatch.

my concern with writing my own template is that i would miss out on things as the library changes/evolves. maybe there's a new zod(ios) feature released that gets added to the default template, i'd have to merge those upstream changes into my local template. i guess it's like maintaining a fork, with all the negatives (and positives!) that entails.

of course this is your project so you can do as you please. so either way, your call :)

this makes sense, especially the upstream changes you got me there (I'm also complaining about this for another project where I needed to fork something while I'd rather avoid it 😭 )

my ideal would be to export a function to customise the zodios instance (so base url can be changed), plus export all the schemas. if people use them great, less divergence from default. if they don't, no harm done. if an object is exported and nobody is around to import it, does it make a sound? haha

is this ok for you ? @WickyNilliams
#71

also, should it be in the grouped template as well ? I did include it for now but a bit unsure

oh okay you want schemas too, i'm.. not a fan of the idea, or at least not without a bit of work

if we were to just add export in front of every zod schema, I'm afraid this would pollute the import namespace (=intellisense autocomplete) & could also slow down TS
one way to do it would be to make an object with all schemas and then export it

would that be fine ? something like

export const schemas = {
    Pet,
    Category,
   // ...
}

done here, can merge if this is fine with you

#71 looks great, an object with all the schemas is fine by me. i can't comment on the grouped template, as i haven't used it and not sure it's purpose (also can't get it to output anything differently in the playground?).

great ! i'll merge

ah well, seems like there's a bug on the playground with the 2 groups templates that are NOT split-files, it seems to work after switching to split-files and then coming back on one of them

basically it groups endpoint by tag or method, just like the name indicates 😅 and you can also generate 1 file for each group

Screenshot 2023-01-17 at 10 13 05

ahh i see. makes sense to include from a consistency perspective i guess. and as discussed, it would get tree shaken if unused