Skip to content

Allow instantiating the Meilisearch client with custom HTTP headers #721

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

wandyou
Copy link

@wandyou wandyou commented Jan 31, 2025

Pull Request

Related issue

Fixes #720

What does this PR do?

  • Fixes the issue by introducing a new option in the meilisearch client builder.
  • Passes it down to the http client
  • Merges the headers passed in the option with the other headers already configured (ex: bearer)

Improvement

  • This solution is not the cleanest because if forces us to null all the optional parameters before it (if we don't use them).
    For example : new Meilisearch(MEILISEARCH_HOST, MEILISEARCH_SEARCH_KEY, null, null, [], null, ["X-MS-USER-ID" => example]) => But it was the fastest solution and the less destructive.
  • An other way would be to create a method in the Meilisearch Client object addHeader()
  • An other way would be to pass all Meilisearch Client options in the form of an array, allowing us to only define used values in any order we like.

PR checklist

Please check if your PR fulfills the following requirements:

  • Does this PR fix an existing issue, or have you listed the changes applied in the PR description (and why they are needed)?
  • Have you read the contributing guidelines?
  • Have you made sure that the title is accurate and descriptive of the changes?

Extra info

First contribution of mine to this repo, maybe I missed some subtilities.

Summary by CodeRabbit

  • New Features
    • Added support for specifying custom HTTP headers when creating a client instance.

@norkunas
Copy link
Collaborator

You can pass a http client configured with your headers, as it's a http client responsibility 🤔

@wandyou
Copy link
Author

wandyou commented Feb 4, 2025

I get it, and that's how I am solving this issue right now.

But the X-MS-USER-ID header is specific to meilisearch's analytics and I find it more appealing and "light" to just be able to pass my unique user identifier while calling new MeilisearchClient(), then passing an instance of a full http client, add configuration options, to "just" give an Analytics header.

In fact in some cases, I would like to be able to change the user-id passed in the header on the go. Maybe with a $client->setHeader()or $client->setUserId(). Because I want to perform a search while being the user and an other while being the server. And having to instanciate two meilisearch clients seems overkill.

It is obvious to me that few only projects will need to pass a "custom" http client to the MeilisearchClient, but all of them would like to take advantage of precise analytics. And therefore pass a "X-MS-USER-ID". So I find it interesting to make that task more "accessible".

Maybe the right thing to do is not to touch the headers upfront, but to expose a method like setAnalyticsUserId()and under the hood it sets the header.

I know analytics is in beta for now, so all of this is maybe new and not much used. But as a developer, not needing to customise my http client. I would prefer having a simple way to pass this info. I did not find any Analytics methods in the php doc neither. For example to report a clic on a search hit, or a conversion.

Maybe I am missing a key concept here and not seeing the big picture, and maybe I am not expressing myself clearly enough because english is not my native language. So obviously feel free to jump in and explain why it would not be the way to go.

Thanks

@wandyou
Copy link
Author

wandyou commented Feb 4, 2025

I may have not been clear enough on the fact that I want to simplify the implementation of X-MS-USER-ID because in my opinion, analytics is a mandatory option for most use cases. And most devs will want to pass it, so why not make it dev friendly ?

Obviously if I want to configure and use custom headers, the best practice would be to pass a custom http client.

I get that adding an optional headers array, whilst seeming the easiest implementation on my end, is not the best suited for the long run.

Maybe a method like setAnalyticsUserId()on the client would ? Or any other suggestions ?

@norkunas
Copy link
Collaborator

norkunas commented Feb 4, 2025

And having to instanciate two meilisearch clients seems overkill.

I wouldn't say so. Stateful singleton is more harmful than instantiating single per user :)

I see in docs it is explicitly related to search endpoint. So I think this could be accepted as a SearchQuery option, but not as a global setting for whole Meilisearch client

@norkunas norkunas requested review from Strift and curquiza February 4, 2025 08:20
@wandyou
Copy link
Author

wandyou commented Feb 4, 2025

I see in docs it is explicitly related to search endpoint. So I think this could be accepted as a SearchQuery option, but not as a global setting for whole Meilisearch client

Well as of for now, analytics is only done on searches, so yes indeed it would make more sense to add it as a Search Query option.

And regarding other analytics endpoints ? Like hit clicking, conversions, etc ? Would be nice to implement those as well.

@norkunas
Copy link
Collaborator

norkunas commented Feb 4, 2025

And regarding other analytics endpoints ? Like hit clicking, conversions, etc ? Would be nice to implement those as well.

Yes, for this you could open another issue :)

Copy link

codecov bot commented Feb 5, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 89.82%. Comparing base (368c73f) to head (4379882).
Report is 70 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #721      +/-   ##
==========================================
- Coverage   90.74%   89.82%   -0.92%     
==========================================
  Files          52       59       +7     
  Lines        1340     1455     +115     
==========================================
+ Hits         1216     1307      +91     
- Misses        124      148      +24     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@Strift Strift added the enhancement New feature or request label Feb 8, 2025
@brunoocasali
Copy link
Member

brunoocasali commented May 15, 2025

So far, since we only use it for the search analytics, and since I don't have any idea if we will extend that to other places, I think it makes sense to be a SearchQuery option indeed.

And regarding other analytics endpoints ? Like hit clicking, conversions, etc ? Would be nice to implement those as well.

This could be a central issue in the https://github.com/meilisearch/integrations-guides repo btw! CC: @macraig @gmourier feedback regarding the future of the analytics :)

@Strift Strift requested a review from Copilot May 21, 2025 07:00
Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR introduces a new option to pass custom headers when building the Meilisearch client, addressing issue #720 by allowing developers to merge custom headers with the pre-configured ones.

  • Added a new $headers parameter (defaulting to an empty array) to the constructors in both the HTTP client and the main client.
  • Merges the custom headers with the existing Authorization header when applicable.

Reviewed Changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
src/Http/Client.php Added an optional $headers parameter and merged it with defaults.
src/Client.php Propagated the new $headers option into the Meilisearch client adapter.

@@ -41,7 +41,8 @@ public function __construct(
?ClientInterface $httpClient = null,
?RequestFactoryInterface $reqFactory = null,
array $clientAgents = [],
?StreamFactoryInterface $streamFactory = null
?StreamFactoryInterface $streamFactory = null,
$headers = []
Copy link
Preview

Copilot AI May 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding a type declaration (e.g. array) for the $headers parameter to improve API consistency and type safety.

Copilot uses AI. Check for mistakes.

@@ -47,9 +47,10 @@ public function __construct(
?ClientInterface $httpClient = null,
?RequestFactoryInterface $requestFactory = null,
array $clientAgents = [],
?StreamFactoryInterface $streamFactory = null
?StreamFactoryInterface $streamFactory = null,
$headers = []
Copy link
Preview

Copilot AI May 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding a type declaration (e.g. array) for the $headers parameter in the constructor to maintain consistency across the client API.

Copilot uses AI. Check for mistakes.

Strift
Strift previously approved these changes May 21, 2025
Copy link
Collaborator

@Strift Strift left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the delayed review. I would improve types if possible, but this can be handled in another PR if we want to merge ASAP.

edit: sorry I approved too quick, adding tests would be welcome here

@Strift Strift dismissed their stale review May 21, 2025 07:06

Missing tests

Copy link
Collaborator

@Strift Strift left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I recommend adding tests to verify that this works as intended.

I would also improve types as recommended by Copilot

Copy link

coderabbitai bot commented May 21, 2025

"""

Walkthrough

The constructors of two Client classes were updated to accept an optional $headers parameter, defaulting to an empty array. This parameter allows users to pass custom headers when creating a client instance. The provided headers are merged with existing defaults, enabling easier customization of HTTP requests.

Changes

File(s) Change Summary
src/Client.php Updated Client constructor to accept an optional $headers parameter and pass it to the adapter.
src/Http/Client.php Modified Client constructor to accept $headers, merging them with default headers for outgoing requests.

Assessment against linked issues

Objective Addressed Explanation
Allow passing custom headers directly in the Client builder (#720)

Poem

A header here, a header there,
Now clients customize with flair!
With just one tweak, you pass your key,
Or track your user easily.
The rabbit hops, the code is neat—
Custom headers, what a treat!
🐇✨
"""


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4379882 and fe09a3c.

📒 Files selected for processing (1)
  • src/Http/Client.php (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/Http/Client.php
✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (2)
src/Client.php (1)

54-54: Add type declaration for $headers parameter

The $headers parameter lacks a type declaration, which is inconsistent with the rest of the parameters in this function signature. Consider adding an explicit array type declaration to maintain consistency and improve type safety.

-        $headers = []
+        array $headers = []
src/Http/Client.php (1)

45-45: Add type declaration for $headers parameter

The $headers parameter lacks a type declaration, which is inconsistent with the rest of the parameters in this function signature. Consider adding an explicit array type declaration to maintain consistency and improve type safety.

-        $headers = []
+        array $headers = []
🧹 Nitpick comments (3)
src/Http/Client.php (3)

38-45: Document the headers parameter format

Consider adding a PHPDoc comment for the $headers parameter to document its expected format and usage. This would align with the class property which is documented as @var array<string,string>.

 /**
  * @param array<int, string> $clientAgents
+ * @param array<string, string> $headers Custom HTTP headers to include in all requests
  */
 public function __construct(
     string $url,
     ?string $apiKey = null,
     ?ClientInterface $httpClient = null,
     ?RequestFactoryInterface $reqFactory = null,
     array $clientAgents = [],
     ?StreamFactoryInterface $streamFactory = null,
     array $headers = []
 ) {

57-57: Document header override behavior

The current implementation allows custom headers to override default headers like 'User-Agent' and 'Authorization'. Consider documenting this behavior, either in the PHPDoc or as a code comment, to prevent unintended consequences.

-        $this->headers = array_merge($this->headers, $headers);
+        // Custom headers take precedence over default headers
+        $this->headers = array_merge($this->headers, $headers);

44-57: Consider architectural alternatives for analytics headers

Based on the PR discussion, there seems to be consensus that analytics headers like X-MS-USER-ID might be better handled at the query level (e.g., as a SearchQuery option) rather than at the client level, since they currently only apply to search endpoints.

While this implementation provides a working solution for custom headers, consider exploring SearchQuery options for analytics-specific headers in a future PR, as this might provide a more appropriate abstraction for this specific use case.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge Base: Disabled due to data retention organization setting

📥 Commits

Reviewing files that changed from the base of the PR and between 520036c and 4379882.

📒 Files selected for processing (2)
  • src/Client.php (1 hunks)
  • src/Http/Client.php (2 hunks)

@Strift Strift changed the title add option to pass headers in the meilisearch client builder Allow instantiating the Meilisearch client with custom HTTP headers May 28, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add option to pass headers directly in the Client builder - For example to easily pass X-MS-USER-ID
4 participants