fabien0102 / openapi-codegen

A tool for generating code base on an OpenAPI schema.
505 stars 62 forks source link

Where to Pass Request Headers? #73

Closed el-j closed 2 years ago

el-j commented 2 years ago

Hi nice project so far.

i was using restful-react and was able to add my jwt after sign in to the request header. now i am a bit stuck as the new "getters" do not have an option for the header...

could you please help how to handle that with openapi-codegen? image

image

el-j commented 2 years ago

sorry i just needed to create the generateReactQueryComponents ... now all is good i think

el-j commented 2 years ago

... no sadly not. i am still in need to set the right headers for the request, but i do not know where or how to do it. at the moment i have no api connection because of a cors block.

could you advice please?

fabien0102 commented 2 years ago

Hi 👋

You can find a walk through here -> https://xata.io/blog/openapi-typesafe-react-query-hooks

The idea is to inject the headers in the generated {namespace}Context

As example this is how we are doing it at xata

  1. Add the type image

  2. Inject the header image

Here we are in a nextjs context, so we retrieve the header with useSession. Everything returns as fetcherOptions in the context file are already injected in the fetcher file.

fabien0102 commented 2 years ago

Adding the types in the step 1 will also add the possibility to pass headers on every request:

image

(example with a mutation)

el-j commented 2 years ago

hi, thank you very much, that saved my day! got the login against the api working again.

i am building a react frontend and i am soooo happy to work with your piece of art! it helps so much! 🚀 we can close this here. very good.

one nice thing for the config: override the apiBaseUrl from the swagger, when generating newly, by the value from the config. or do i miss something from the options to do that? image

background: the swagger is from the running build of a project, the dev-api is for my dev-purposes. so if i generate, i always will end up with the wrong api-url in my generated fetchers.ts. as it is generated, i do not want to manipulate it by hand or script. could an optional apiBaseUrl override practical for the generator?

i would love it or don't see the option if there is one already ;)

el-j commented 2 years ago

or even better: how to set the apiBaseUrl on runtime, this would be very very nice.

fabien0102 commented 2 years ago

For the baseUrl you can directly modify the {namespace}Fetcher, this file is just a template meant to be tweak (and take the url from the spec as example)

If you want to set this value at runtime, you can add this in FetcherOptions as for the headers (and inject the value manually on each request or inside the context)

Please note that {namespace}Fetcher and {namespace}Context are generated only if the files are not there (they don't have the Generated by @openapi-codegen header) this is where you can handle any extra logic. This is a different approch from restful-react, where everything was in the config! The nice thing about this, is that you are manipulating real typescript code instead of strings in a config file.

The only constraint that you have are the types, if typescript is happy, you are good to go!

el-j commented 2 years ago

Ok in the meantime i changed my config-reader + creator to find the baseUrl in the fetcher.ts file and replace it with a setBaseUrl function that sets the baseUrl as a let for runtime.

fs.readFile(theFetcherFile, 'utf8',(err,data) => {
          if (err) {
            return console.log(err);
          }
          console.log("and its content:>>>>>", data, theFetcherFile);
          let replaceRegEx = /(^const baseUrl = ")+(http[s]?:\/\/)?([^\/\s]+\/)(.*)/gm
          let oldUrl = data.match(replaceRegEx)[0].split('"')[1]
          console.log("old Url",data.match(replaceRegEx),oldUrl)
          let createNewUrl = `let baseUrl:string = ''; export const setBaseUrl = (newUrl: string ,oldUrl: string = "${oldUrl}")=> {  if (!newUrl) {baseUrl=oldUrl; return oldUrl} else {baseUrl=newUrl; return newUrl }};`
          var result = data.replace(replaceRegEx, createNewUrl);
          console.log("and replaceing:::>>>>>>", result);
          return fs.writeFileSync(theFetcherFile, result)

        })

resulting in a fetcherFile with:

let baseUrl: string = '';
export const setBaseUrl = (newUrl: string, oldUrl: string = "https://api.enginsight.com/") => {
  if (!newUrl) { baseUrl = oldUrl; return oldUrl }
  else { baseUrl = newUrl; return newUrl }
};

now i set the baseUrl on app-start from the config like i used to do it with restful-react ;)

fabien0102 commented 2 years ago

Since the fetcher is generated only one time (if the file doesn't exist) you could just modify it 😅 But I'm glad you found a way to make it work.

I will close this issue for now, please don't hesitate if you have other questions

el-j commented 2 years ago

https://xata.io/blog/openapi-typesafe-react-query-hooks @fabien0102 maybe you could have this link shared in the readme? it helps a lot to understand how to use this nice piece of software ;)