hey-api / openapi-ts

✨ Turn your OpenAPI specification into a beautiful TypeScript client
https://heyapi.vercel.app
MIT License
634 stars 44 forks source link

Setting user-agent #707

Closed Zyles closed 5 days ago

Zyles commented 1 week ago

Description

How do you set a custom user-agent?

I tried using interceptors but nothing happened:

import { getAllPets } from '@/lib/pet-store/services.gen'
import { client } from '@hey-api/client-fetch'

client.interceptors.request.use((request) => {
  request.headers.set('User-Agent', 'My user agent')
  return request
})
mrlubos commented 1 week ago

@Zyles Why do you believe this is how you set user agent?

Zyles commented 1 week ago

@Zyles Why do you believe this is how you set user agent?

I don't know. I tried using createClient, but there is something I seriously cannot wrap my head around with this package.

I want multiple API clients to different APIs which I generated using the codegen. Some endpoints need authentication and some do not.

I created a wrapper like this:

import { createClient } from '@hey-api/client-fetch'

const apiClient1 = createClient({
  baseUrl: 'https://api1.domain.com',
  global: false,
  headers: {
    'User-Agent': 'Foobar 1.0'
  }
})

apiClient1.interceptors.response.use((response) => {
  if (response.status === 200) {
    console.log(`Request to ${response.url} was successful`)
  } else {
    console.error(`Request to ${response.url} returned an error: ${response.status}`)
  }
  return response
})

export default apiClient1 

But how do I use this apiClient1 instance in my requests?

The demo shows calling the methods directly:

import { getAllPets } from '@/lib/apiclient1/services.gen'

async function getAllPetsFromApi() {
  const response = await getAllPets()

  setResponse(response)

  return response
}

But then I am not using my apiClient1 wrapper, but instead the default client that was generated.

Also the demo uses

await getPetById({
      client: localClient,

But using client: to inject a localClient is not supported in the code that got generated for me.

What am I missing?

mrlubos commented 1 week ago

@Zyles it's hard to say without seeing your code, but my best guess would be you're not setting client: '@hey-api/client-fetch' in your Hey API config file and perhaps using the default legacy fetch client. Regarding user agent, I am not sure why you need to do that at all, but I'm not aware that's the way to do it, see https://stackoverflow.com/questions/23248525/setting-a-custom-useragent-in-html-or-javascript

Zyles commented 6 days ago

User-agent should be set in the client.

Using normal axios client it is as simple as:

const apiClient= axios.create({
  baseURL: config.baseUrl,
  headers: {
    'User-Agent': 'Foobar',
    Accept: 'application/json',
    'Content-Type': 'application/json'
  }
})

It can also be done on a request basis by passing a headers object.

Does the fetch client not support this?

Looking at the docs I don't understand how to use multiple clients. It mentions configuring a global client. But we have multiple different APIs we need to call and each needs their own client.

And how do you use authorization only on endpoints that require it but not the rest?

For example this request requires a token (code generated by your lib):

export const getOrders = (data: GetOrdersData): CancelablePromise<GetOrdersResponse> => { return __request(OpenAPI, {
    method: 'GET',
    url: '/orders/',
    path: {
    },
    headers: {
        'If-None-Match': data.ifNoneMatch
    },
    query: {
        token: data.token
    },
    errors: {
        304: 'Not modified',
        400: 'Bad request',
        401: 'Unauthorized',
        403: 'Forbidden',
        420: 'Error limited',
        500: 'Internal server error',
        503: 'Service unavailable',
        504: 'Gateway timeout'
    }
}); };
Zyles commented 6 days ago

I am using Electron and found out I can set the user-agent using their API:

mainWindow.webContents.setUserAgent('Foobar 1.0')

Now the question remains, how to use multiple clients with different config and auth per endpoint?