Skip to content

Terminology #40

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

Merged
merged 43 commits into from
Sep 27, 2015
Merged

Terminology #40

merged 43 commits into from
Sep 27, 2015

Conversation

sagikazarmark
Copy link
Member

This PR tries to solve #38

Some points to discuss:

  • Exceptions in the package: concrete implementations? Exception naming?
  • Interface names: PsrClient, HttpClient, Client? (proposed by @dbu HttpPsrClient, HttpMethodsClient, HttpClient)
  • Add ClientTemplate: better name?

To do before merging:

  • Squash commits!!!!!!!

To do after merging:

  • Move the package to client (preserve the package here as well for historical reasons (0.1 release)?)

@sagikazarmark
Copy link
Member Author

@hannesvdvreken FYI

@hannesvdvreken
Copy link
Contributor

@sagikazarmark I'm watching this repo so saw the PR ;-) I'll have a look tomorrow.

@sagikazarmark
Copy link
Member Author

Well, my personal experience is that people tend to look at Github messages more actively if they are specifically mentioned. 😉

Sure, no hurry.

@hannesvdvreken
Copy link
Contributor

I've gone through the changes quickly and I think it's very clear now.

The adapter packages just implement the PsrHttpClient interface, right? There will be a HttpClient and a Client class which wraps a PsrHttpClient and provides the interfaces and still expose the PsrHttpClient methods.

Didn't take an in depth look to find mistakes because time constraints, but I thrust it will be close to perfect ;-)

@sagikazarmark
Copy link
Member Author

The adapter packages just implement the PsrHttpClient interface, right?

Basically, yes.

There will be a HttpClient and a Client class which wraps a PsrHttpClient and provides the interfaces and still expose the PsrHttpClient methods.

The plan is to have something called adapter client which is a wrapper around a PsrHttpClient and yes, still implements it.

Something like:

class AdapterClient implements Client
{
public function __construct(PsrHttpClient $psrHttpClient) {}
}

@sagikazarmark
Copy link
Member Author

@hannesvdvreken thanks for feedback. What do you think about the TODOs I mentioned in the issue description?

use Psr\Http\Message\ResponseInterface;

/**
* Interface for HTTP conventional methods
Copy link
Contributor

Choose a reason for hiding this comment

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

maybe say "Interface for HTTP requests without the PSR-7 RequestInterface"

Copy link
Member Author

Choose a reason for hiding this comment

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

Hm. Sounds good, but does it really explain what this interface is about? The point is rather about HTTP methods than the lack of RequestInterface.

Copy link
Contributor

Choose a reason for hiding this comment

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

then maybe just add a second line saying: "Use this interface when you do not have PSR-7 RequestInterface instances available."

Copy link
Member Author

Choose a reason for hiding this comment

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

👍

@sagikazarmark
Copy link
Member Author

Another major change I am thinking about: currently post, put, patch, delete and options request in HttpClient have two type of body fields: $data = [], array $files = [].

$data can be string, array, StreamInterface, while $files are always an array of files.

Furthermore, if $data is stream interface than $files should not be passed (hence the body is already prepared).

I see the reasoning behind, it was hard for @egeloen to create an easy, but full solution. It is still a little bit weird, so I am thinking about the following:

I would create a Body interface with the following implementations:

  • Stream: accepts a stream interface
  • String: accepts a string body
  • Data: accepts an array body
  • Files: accepts files
  • Combined: accepts a Data and a Files object

With the exception of Stream these objects would be string castable which can be used then to create a Stream object.

This is obviously extra complexity, but I came up with the idea, because I think it can be confusing this way as well. Also, much of the body creating logic can be moved to the Body classes and the client should only handle string to stream conversion.

What do you think?

@sagikazarmark
Copy link
Member Author

Let's continue the body discussion in #42

@sagikazarmark
Copy link
Member Author

@dbu Ideas for ClientTemplate naming? HttpMethods for example? Since it only "implements" the HTTP methods, send still needs to be implemented. Not sure though, because it might collide with HttpMethodsClient.

@dbu
Copy link
Contributor

dbu commented Aug 26, 2015 via email

@sagikazarmark
Copy link
Member Author

#26 should also be addressed here.

sagikazarmark and others added 2 commits August 26, 2015 22:36
Add Body implementations

Remove Data body interface, common interface is not needed

Add Content headers to Body

Body is optional, add HttpMethods trait

Refactored body implementations
Add Body implementations
@ddeboer
Copy link
Contributor

ddeboer commented Sep 22, 2015

Sorry to chime in so late, but I have some doubts about the mix between interfaces and ‘convenience’ classes such as those in the Body\ namespace, as it seems to break single responsibility. An adapter package (such as php-http/guzzle6-adapter) would only need the interfaces, as the body etc. classes are already available in Guzzle itself. Or is the idea that the adapters also translate between Guzzle’s own Body etc. implementation and the PHP-HTTP ones?

@sagikazarmark
Copy link
Member Author

The Body classes are supposed to replace the InternalRequest object in Ivory. The point is that you can use these clases to provide custom type data (like files) to the convenience method calls. They are completely optional and can be translated into an array of content headers and a string which then can be passed to the message factory. Guzzle 6 adapter probably won't need it, as they are related to the convenience methods, adapters does not need to implement those. I plan to create a separate "adapter/client" for that which accepts an HttpPsrClient and implements HttpMethodsClient.

@ddeboer
Copy link
Contributor

ddeboer commented Sep 22, 2015

That they are optional is exactly the problem that I have with them. The Body classes have mostly to do with messages, don't they? In that case, they could go into a separate message package that only clients that need them depend on.

@sagikazarmark
Copy link
Member Author

The Body interface is part of the contract, it is used in HttpMethodsClient. The basic implementations provided are small. That said, it is still implementation and you might be right about moving them into a utility package. There is another BatchRequest trait work in progress which is also something like that.

My only concern about it is in that case the utility package must require the contract, which in turn can lead to a dependency hell: an adapter/client requires both the contract and the utility. If versions doesn't match, you can't install the adapter.

@dbu
Copy link
Contributor

dbu commented Sep 25, 2015 via email

@sagikazarmark
Copy link
Member Author

I hope that major version bumps will be extremely rare, so we might not even face this dependency hell issue we are afraid from. The only condition is to have well-designed interfaces, which we are working on right now.

@joelwurtz
Copy link
Member

IMO we can leave utility classes in this package (client), as if they are not used they don't add anything expect for the disk size.

@sagikazarmark
Copy link
Member Author

Yes, they do. Bandwidth, package complexity, autoloading. These are minor things, but imagine the package installed a thousand times.

@sagikazarmark
Copy link
Member Author

Any last words before merging this one?

@sagikazarmark
Copy link
Member Author

Let's continue the utility discussion in #56

@joelwurtz
Copy link
Member

I think this can be merged, anyways it's an alpha release and there is still room for other alpha release if big change come up with new discussions

@joelwurtz
Copy link
Member

A remark about the Body, if it is split into an Utility package, all adapter implementing the HttpMethodsClient interface will then have to depend on this package ?

@sagikazarmark
Copy link
Member Author

Nope. The Body interface remains in this package. Optionally the implementations should be moved to the utility package.

/**
* Convert data to a format which can be used to create a proper PSR-7 Stream
*
* @return string|StreamInterface
Copy link
Member

Choose a reason for hiding this comment

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

PSR7 Only allow StreamInterface no string

Copy link
Member Author

Choose a reason for hiding this comment

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

Nope, string is a valid return type here as well. Keep in mind that this interface is used in the MethodsClient where you probably use a MessageFactory.

Copy link
Member

Choose a reason for hiding this comment

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

Yes but it may conflict with some implementations like diactoros where the string is an url to stream and not a content. But maybe the string here as the same purpose ? In this case we should add documentation about the string return value.

Copy link
Member Author

Choose a reason for hiding this comment

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

We have a custom MessageFactory interface which is recommended to be used. This ensures you can use whatever PSR7 implementation in your clients. There is already some kind of documentation about it, for reference check the docs repo.

Presonally I think that the diactoros behavior is a bit weird. I think using string as a simple body is much more logical than using it as a URL to a stream.

Copy link
Member

Choose a reason for hiding this comment

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

I agree, i'm working on the socket adapter right now and using diactoros (only for the init puprose) feel weirds when implementing the send method :/

Copy link
Member Author

Choose a reason for hiding this comment

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

Check the docs here: http://php-http.readthedocs.org/en/latest/

We have a zero-config discovery service which let you just use the available implementation AND message factory.

Copy link
Contributor

Choose a reason for hiding this comment

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

nonetheless we should explain what the string we allow to return here is. if we allow a string at all - it seems like an ambiguity. ideally we would even eliminate string as return completely. otherwise a consumer needs to check whether it got a string or a stream and do different things...

Copy link
Member Author

Choose a reason for hiding this comment

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

We have already discussed this in another issue. Body objects would need a message factory to return a stream object. And that's one simple IF to check the input parameter.

The alternative is to remove body types entirely and use "generators" which can populate the request based on a specific input. It would certainly make the contract cleaner. And we could move that code to the utility package.

Copy link
Member Author

Choose a reason for hiding this comment

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

That would also mean, that requests sent through HttpMethodsClient must be populated from the generator manually.

*
* @return string|StreamInterface
*
* @throws Exception
Copy link
Contributor

Choose a reason for hiding this comment

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

this being an interface we could also say what circumstances might typically lead to exceptions.

sagikazarmark added a commit that referenced this pull request Sep 27, 2015
@sagikazarmark sagikazarmark merged commit f6503da into master Sep 27, 2015
@sagikazarmark sagikazarmark deleted the terminology branch September 27, 2015 21:48
Nyholm pushed a commit to Nyholm/httplug that referenced this pull request Dec 26, 2019
POC how to not be dependent on discovery

Fix unit tests

Fix factory method

Remove duplicated service

Move discovery to compiler pass

Applied fixes from StyleCI

Fix puli executable

Use class constant

Fix puli command order

Fix lowest dependency issue

Fix HHVM tests

Improve tests
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants