opensearch-project / opensearch-php

Official PHP Client for OpenSearch
Other
110 stars 58 forks source link

Psr interfaces #233

Open kimpepper opened 1 month ago

kimpepper commented 1 month ago

Fixes #199

Description

This PR removes the dependency on a specific HTTP client implementation and introduces PSR-7, PSR-17 and PSR-18 interfaces.

Issues Resolved

It greatly simplifies the volume and complexity of the library codebase and removes the need to manage:

Users of this library can choose from a number of synchronous and asynchronous HTTP clients including:

It greatly simplifies the volume and complexity of the library codebase. Specifically, it:

Breaking changes

Tasks:

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license. For more information on following Developer Certificate of Origin and signing off your commits, please check here.

dblock commented 1 month ago

I noticed you tried to fix DCO?

"Kim Pepper [kim@previousnext.com.au](mailto:kim@previousnext.com.au)", but got "Kim Pepper [kim@pepper.id.au](mailto:kim@pepper.id.au)".

Something is not adding up between your settings and the commit signature.

kimpepper commented 1 month ago

I noticed you tried to fix DCO?

"Kim Pepper [kim@previousnext.com.au](mailto:kim@previousnext.com.au)", but got "Kim Pepper [kim@pepper.id.au](mailto:kim@pepper.id.au)".

Something is not adding up between your settings and the commit signature.

I think I fixed that now? Let me know if it's still not rigt.

I've updated the ClientBuilder and refactored the endpoints callable into it's own factory class. I think this makes it easier to understand, and also allows clients to swap out an implementation or use a dependency injection container if they want.

I updated the client and namespace templates also. I regenerated afterwards and it looks like there are a lot of new API methods added. Should I use something other than https://github.com/opensearch-project/opensearch-api-specification/releases/download/main-latest/opensearch-openapi.yaml ?

shyim commented 1 month ago

I think setHandler are not working anymore right? So aws sig v4 needs to be adjusted?

kimpepper commented 1 month ago

I think setHandler are not working anymore right? So aws sig v4 needs to be adjusted?

Yes, I think we'd need to rewrite the guzzle middleware/handler without the ring dependency to make it easier for people who use AWS OpenSearch service to use signed requests.

dblock commented 1 month ago

Something is not adding up between your settings and the commit signature.

I think I fixed that now? Let me know if it's still not rigt.

Yep looks good.

I've updated the ClientBuilder and refactored the endpoints callable into it's own factory class. I think this makes it easier to understand, and also allows clients to swap out an implementation or use a dependency injection container if they want.

👍

I updated the client and namespace templates also. I regenerated afterwards and it looks like there are a lot of new API methods added. Should I use something other than https://github.com/opensearch-project/opensearch-api-specification/releases/download/main-latest/opensearch-openapi.yaml ?

Let's work on merging https://github.com/opensearch-project/opensearch-php/pull/223 separately from this not to mix in the PSR changes. It needs some attention to tests. If nobody picks it up here I can do it soon.

dblock commented 1 month ago

Fixed CI in https://github.com/opensearch-project/opensearch-php/pull/234. Will merge and make a release with #223 next.

kimpepper commented 1 month ago

Thinking about this more, returning HTTP Response might not be the best DX.

We should introduce a Response object that contains the body of the HTTP Response and any meta-data. We can add a toArray method to return the deserialized JSON. We can have 2 sub-classes ErrorResponse and OKResponse. The error response can have getErrorCode() and getErrorMessage() methods.

The Promise would also return this too.

Thoughts?

dblock commented 1 month ago

@kimpepper In other clients we return a strongly typed object that derives from a base class that also gives access to the underlying raw HTTP response from the network library "as is" along with some helper methods like status code or raw body. Note that OpenSearch returns more than JSON, too.

dblock commented 1 month ago

I fixed what was broken in https://github.com/opensearch-project/opensearch-php/pull/223 and merged, rebase.

kimpepper commented 3 weeks ago

@kimpepper In other clients we return a strongly typed object that derives from a base class that also gives access to the underlying raw HTTP response from the network library "as is" along with some helper methods like status code or raw body. Note that OpenSearch returns more than JSON, too.

I think the strongly typed object would require a lot of work on the generator side and might be out of scope for this issue?

Not sure whether it's worth a simple wrapper around the PSR Response and HTTP Promise that gets returned?

kimpepper commented 3 weeks ago

From my understanding the response content types can be one of:

but I couldn't find the docs to back that up.

dblock commented 3 weeks ago

I think the strongly typed object would require a lot of work on the generator side and might be out of scope for this issue?

100%

Not sure whether it's worth a simple wrapper around the PSR Response and HTTP Promise that gets returned?

I would if we think it makes it easier to extend it later in a common way across multiple transports (it feels like it would).

dblock commented 3 weeks ago

From my understanding the response content types can be one of:

  • plain text
  • json
  • nd-json
  • xml

but I couldn't find the docs to back that up.

We cover the range in https://github.com/opensearch-project/opensearch-api-specification, see https://github.com/opensearch-project/opensearch-api-specification/blob/07e329e8d01fd0576de6a0a3c35412fd5a9163db/tools/src/tester/MimeTypes.ts#L10.

OpenSearch returns plain text, JSON, nd-json, CBOR, SMILE, and YAML, most from cat APIs.

Did you see XML somewhere? That may be a miss in API specs :)

kimpepper commented 3 weeks ago

I created a separate PR #236 to deal with the bulk change to static return types.

kimpepper commented 3 weeks ago

Split out #237 for the endpoint factory changes here.

dblock commented 3 weeks ago

Thanks @kimpepper! Let's work through those.

kimpepper commented 3 weeks ago

Thanks for your review @stof . I'm holding off any changes here until the dependent issue #237 lands.

dblock commented 1 week ago

@kimpepper rebase let's see what this looks like?

kimpepper commented 1 week ago

@kimpepper rebase let's see what this looks like?

I think there is a fair bit to do if we are dropping async support in this PR.

kimpepper commented 1 week ago

I did a basic rebase off main but this is still pretty rough. I'm not sure how we plan on handling BC.

Should we split off removing the async client?

kimpepper commented 1 week ago

Thinking about this a bit further, we can keep the existing Transport, deprecate it, and introduce a new PsrTransport.

Still need to figure out how to handle BC for the return types.

dblock commented 1 week ago

This one is a major upgrade that is definitely worth it, so I would introduce this as a breaking change. This is also the right time to change what these APIs return and really try to pack all the breakages in one major upgrade.

stof commented 1 week ago

This PR seems to remove all support for sigv4. Shouldn't it provide a PSR client decorator implementing the sigv4 logic, as all other opensearch clients are shipping support for sigv4 to support the AWS managed opensearch service ?

dblock commented 1 week ago

This PR seems to remove all support for sigv4. Shouldn't it provide a PSR client decorator implementing the sigv4 logic, as all other opensearch clients are shipping support for sigv4 to support the AWS managed opensearch service ?

Yes, we definitely do not want to lose Sigv4 functionality. Breaking change is OK, but we need all the existing features.

kimpepper commented 1 week ago

In the other issues we are trying to keep a BC layer for the 2.x branch. Are we saying this PR would go straight into a 3.x branch without any deprecations in 2.x?

If we try to get this in 2.x and provide BC this PR will:

This seems like quite a lot. Do you agree with the approach? Do you think we can split any of this out to sub-tasks or follow-ups?

dblock commented 1 week ago

In the other issues we are trying to keep a BC layer for the 2.x branch. Are we saying this PR would go straight into a 3.x branch without any deprecations in 2.x?

All breaking changes must go to main which will be the next major version of the client (3.0.0).

Drop async support (aparrently not working anyway according to https://github.com/opensearch-project/opensearch-php/pull/219#discussion_r1715828607

If it's really not working and never worked, it's not a feature, and we can take a delete in 2.x before this to trim the code.

Only breaking changes warrant a 3.0. If the sum of these can be done in a way of being deprecated -> added then we can continue doing it incrementally. I think you know best @kimpepper :)

kimpepper commented 1 week ago

Yes, the intention is to provide deprecations in 2.x to allow users to upgrade to the Psr approach before 3.x is released.

kimpepper commented 1 week ago

I've pushed new code to implement the concepts above

I haven't looked at tests yet.

stof commented 1 week ago

@dblock async requests are working in the existing codebase for the method allowing to do a raw request (Client::request) but that's all. None of the generated SDK methods allow configuring the async option when calling performRequest, so the support for async requests in the Transport is only for Client::request. This PR was adding async in all methods though a global switch, making all return types blurry.

dblock commented 1 week ago

@dblock async requests are working in the existing codebase for the method allowing to do a raw request (Client::request) but that's all. None of the generated SDK methods allow configuring the async option when calling performRequest, so the support for async requests in the Transport is only for Client::request. This PR was adding async in all methods though a global switch, making all return types blurry.

Got it. I would remove it and see if anyone complains, but technically it's a breaking change. I will 🙈 if it gets removed.