Sometimes it is necessary to send a request to Elasticsearch for something that simply does not exist in Hibernate Search. Let's say an administration command, for example.
Currently, the only option for users is to create their own client and use that. They cannot use our client.
If we want to change that, we have three options:
Expose our internal client, something like ElasticsearchBackend.getClient() returnin a org.elasticsearch.client.RestClient.
Promote our own abstraction layer (org.hibernate.search.v6poc.backend.elasticsearch.client.impl.ElasticsearchClient, org.hibernate.search.v6poc.backend.elasticsearch.client.impl.ElasticsearchRequest, org.hibernate.search.v6poc.backend.elasticsearch.client.impl.ElasticsearchResponse, GSON, ...) to API and expose that.
Create an additional abstraction layer on top of our own and expose that.
I would much rather do 3., so that we are not stuck with the current technologies (Apache HTTP Client + GSON) forever just because they are exposed through our APIs. Especially since we already considered switching from GSON to something else (HSEARCH-2817, HSEARCH-2835) and from the Apache HTTP Client to something else.
Note the "additional abstraction layer" could be very thin and very simple: it would be very close to our own abstraction layer, it would only be a matter of requring the body elements to be passed as strings instead of GSON's JsonObjet.
I suspect users will want to have access to the high level Elasticsearch client instead of the low level one.
We could wrap the client with our own facade but that has two drawbacks:
it implies it's an API / SPI which means we endorse its usage
we would need to track the ElasticSearch API closely to make sure we expose any new things they might add
So I prefer proposal 1. : allow to grab a reference to "our" org.elasticsearch.client.RestClient, yet not introducing an ad-hoc method to accomplish this.
There are two options to do that:
either we explain how to use the ServiceRegistry to grab a ElasticsearchClientFactory - not ideal as you'd still need to initialize a new client instance, not to mention using the services is a bit verbose.
enhance SearchFactory#unwrap - a bit tricky to implement but should be doable
My preference is the unwrap() method.
Drawbacks: I would not attempt to decorate/protect/enhance the returned client, which means people could in theory close it, change the hosts, or do other nasty things but IMO that's the level of control they are asking for.
Ideally we could ask the Elasticsearch team to introduce a safe facade for such use cases but such a contract belongs in the Elasticsearch client project.
Lools like the Elasticsearch team is planning to introduce such an immutable view on the client: