typesense / typesense-instantsearch-adapter

A JS adapter library to build rich search interfaces with Typesense and InstantSearch.js
MIT License
402 stars 63 forks source link

how to use sendApiKeyAsQueryParam with instantsearch react? #187

Open weiklr opened 11 months ago

weiklr commented 11 months ago

Description

Even though i set sendApiKeyAsQueryParam to false when i create a new TypesenseInstantSearchAdapterOptions react-instantsearch still sends queries with X-TYPESENSE-API-KEY http header.

How do i override react-instantsearch and make it post the api key under the payload body instead? I have a very long api key (> 2000 characters), and it's not going through some api gate ways as their request header limit is small.

Steps to reproduce

const generateTypesenseInstantsearchAdapterOptions = (): TypesenseInstantsearchAdapterOptions => {
  // Search settings for full search
  return {
    server: {
      apiKey: '',
      nodes: [
        {
          host: ApiSettings.HOST,
          port: ApiSettings.PORT,
          protocol: ApiSettings.PROTOCOL,
        },
      ],
      sendApiKeyAsQueryParam: false,
    },
  };
};

const typesenseInstantSearchAdapter = new TypesenseInstantsearchAdapter(typesenseOptions);
const searchClient = typesenseInstantSearchAdapter.searchClient;

      <InstantSearch
        searchClient={searchClient}
        indexName={INDEX_NAME}
        onStateChange={onStateChange}
        initialUiState={getInitialUiState()}
      >
     </InstantSearch>

Expected Behavior

I expect react-instant search not to send X-TYPESENSE-API-KEY when a query is sent

Actual Behavior

react-instant search still sends api key with the header Typesense Version: 0.23.1

OS: Ubuntu

jasonbosco commented 11 months ago

By default Typesense sends API keys via an HTTP header, and if you set sendApiKeyAsQueryParam: true it sends it as a query parameter, instead of an HTTP header.

So when you set sendApiKeyAsQueryParam: false it falls back to the default behavior of sending it as an HTTP header.

To send the API key in the post body, you want to do something like this:

const generateTypesenseInstantsearchAdapterOptions = (): TypesenseInstantsearchAdapterOptions => {
  // Search settings for full search
  return {
    server: {
      apiKey: '',
      nodes: [
        {
          host: ApiSettings.HOST,
          port: ApiSettings.PORT,
          protocol: ApiSettings.PROTOCOL,
        },
      ],
    },
    additionalSearchParameters: {
      'x-typesense-api-key': 'YOUR-LONG-API-KEY',
    },
  };
};
weiklr commented 11 months ago

Thanks! making the api key as part additionalSearchParameters as advised, and now the api key gets sent as a query parameter. my request url is now: https://typesense-server.com/multi_search?x-typesense-api-key=[some long api key]

Is there a way to exclude the api key from the request url and make it part of the post body exclusively? I think if the url is too long (our api key is around 53kb currently) it might still get rejected by gateways like cloudflare.

jasonbosco commented 11 months ago

You want to set server.apiKey: '' (blank value), which essentially makes it a no-op and the query param will be blank (it will only have the name x-typesense-api-key). The key inside additionalSearchParameters takes precedence, which is what's sent in the post body.

weiklr commented 11 months ago

I see what you mean. Yeah it works as intended now. I decided to set sendApiKeyAsQueryParam: false instead as the url came out looking like https://typesense-server.com/multi_search?x-typesense-api-key= if i just set apiKey to ''

Thanks for the quick response!