Skip to content
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

[PHP] API client using guzzle6 & psr7 instead of curl #5190

Merged
merged 37 commits into from
Apr 3, 2017
Merged

[PHP] API client using guzzle6 & psr7 instead of curl #5190

merged 37 commits into from
Apr 3, 2017

Conversation

baartosz
Copy link
Contributor

@baartosz baartosz commented Mar 24, 2017

PR checklist

  • Read the contribution guidelines.
  • Ran the shell/batch script under ./bin/ to update Petstore sample so that CIs can verify the change. (For instance, only need to run ./bin/{LANG}-petstore.sh and ./bin/security/{LANG}-petstore.sh if updating the {LANG} (e.g. php, ruby, python, etc) code generator or {LANG} client's mustache templates)
  • Filed the PR against the correct branch: master for non-breaking changes and 2.3.0 branch for breaking (non-backward compatible) changes.

Description of the PR

Finally finished #1482. Looks massive but without generated samples its roughly 10 files changed plus few new test classes. Large feature anyway.
Important points:

  • decided not to follow suggestion and to remove ApiClient altogether and make generated API classes call Httplug's Client interface directly. Otherwise It would be messy abstraction (PetApi -> ApiClient -> HttpClient -> Guzzle/Curl/whatever) plus impossible to leverage fancy new features curl was missing (like streams in responses)
  • deleted generated autoload.php as it make no sense to use it when its necessary to install httplug and guzzle with composer and use vendor/autoload.php
  • tested with guzzle client (php-http/guzzle6-adapter + guzzlehttp/guzzle) and curl client (php-http/curl-client). Works nice with both of them. Only thing not working currently with curl client was file upload. I left it for another iteration/separate ticket. Tests are currently ran only with guzzle.
  • ObjectSerializer had some methods static some not. I tried to make all methods not static and inject it to Api object but ran into issue here https://github.com/swagger-api/swagger-codegen/blob/master/samples/client/petstore/php/SwaggerClient-php/lib/Model/Pet.php#L390. Finally decided to make it all static for consistency and rework it later
  • BC breaks:
    • new dependencies (obviously)
    • initialization of the API class is slightly changed (client adapter has to be passed as argument) (no way around that)
    • removed options from Configuration class (client-specific options go to client now)
    • headers returned as array from $response->getHeader($name); (its how psr7 expects it to work)

Please let me know if its better to make it optional like --library=httplug or something.

@wing328 wing328 added this to the v2.2.3 milestone Mar 25, 2017
@wing328
Copy link
Contributor

wing328 commented Mar 25, 2017

@baartosz thanks for the contribution. We'll review and let you know if we've any question.

cc @arnested @abcsum

@wing328
Copy link
Contributor

wing328 commented Mar 25, 2017

cc @dkarlovi , @scop as well since they also filed several PRs before to improve the PHP API client.

git checkout -b baartosz-php_httplug2 2.3.0
git pull https://github.com/baartosz/swagger-codegen.git php_httplug2

@dkarlovi
Copy link
Contributor

I'm all for dropping the shipped client as it will make the generated code much more simple, focus of this projects is not to generate HTTP clients.

The problem I see is relying directly on Guzzle interface directly, the whole point of PSR-7 is NOT to do that. Generated code should rely on PSR-7 exclusively and enable me to use whatever compatible implementation. This would make integrating the SDK much harder than it should be.

For example, you might already have a PSR-7 compatible client in your app pre-configured, you should be able to just inject it and use it. This means generated code should rely on functionality provided by the interface, for example Streams.

@dkarlovi
Copy link
Contributor

Also: having this behind an option seems reasonable, but I think it would make supporting other libraries messy. What I feel would be a much cleaner approach is to do a "base" PSR-7 only implementation which wouldn't be able to work without injecting the client at all.

Then, --library=httplug would mean we generate an additional class which modifies composer.json and preconfigures everything to be ready to use (so, libraries only add the implementation to use, not modify anything).

@baartosz
Copy link
Contributor Author

@dkarlovi i see your point. So basically instead of httplug provide own interface for the client and optional --library to have one already there?

guzzle/psr7 now is used to provide helpers e.g. To build multipart requests. Are you suggesting writing it from scratch instead?

@dkarlovi
Copy link
Contributor

@baartosz pretty much, yes. If you have a functional PSR-7 client enabled, you can just inject it and have it work with the generated SDK. For example, your HTTP client might have a logger set up which stores all requests to Elastic search, you don't want to have another client which does the same thing, but lacks integration to your environment.

I don't suggest writing anything from scratch, no, the whole point of removing the HTTP client is avoid doing that. :) Can you point me to where exactly you're constructing multi-part messages? It might be an XY problem.

@dkarlovi
Copy link
Contributor

@baartosz BTW thank you very much for your contribution, it's a great effort on your part.

@baartosz
Copy link
Contributor Author

baartosz commented Mar 25, 2017

@dkarlovi makes sense. At this point generated client is using psr7 compatible request and response, so client itself is easy to replace with whatever is decided.

Multipart stream from guzzle/psr7 is used here: https://github.com/swagger-api/swagger-codegen/pull/5190/files#diff-ae9e1fe068c165f6731482ae703b427dR132. Same case with GuzzleHttp\Psr7\Request and GuzzleHttp\Psr7\Response - it's just implementation of psr interface so I don't see any problem using it still even if httplug will be removed.

Thanks for feedback.

* @var string
*/
protected $curlConnectTimeout = 0;
protected $host = '{{basePath}}';
Copy link
Contributor

Choose a reason for hiding this comment

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

Please use unescape basePath instead: {{{basePath}}}

@@ -123,51 +109,6 @@ class Configuration
protected $tempFolderPath;

/**
* Indicates if SSL verification should be enabled or disabled.
Copy link
Contributor

Choose a reason for hiding this comment

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

I notice that the SSL, proxy and timeout methods have been removed. Can you share more with me how a developer will set SSL, proxy, timeout in the new client?

Copy link
Contributor

Choose a reason for hiding this comment

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

@wing328 idea is to remove the HTTP client implementation completely and inject a PSR-7 capable client such as Guzzle.

This means setting up these kinds of configuration would be outside of scope of generated code, it would assume the injected client is capable of being configured properly in its own right. This code would just use it as-is.

Copy link
Contributor

Choose a reason for hiding this comment

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

@dkarlovi thanks for explaining more. To ease the migration, I think we will need to provide auto-generated documentation on how to set these values using Guzzle (the default PSR-7 http client)

Copy link
Contributor Author

@baartosz baartosz Mar 29, 2017

Choose a reason for hiding this comment

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

@wing328 Need some guidance here. I am not sure about priorities - is it more important to have working client out of the box, or having more flexible one?
Should we add client or httplug+client dependencies by default?
Is enough to provide generated apis classes calling send($request) on some ApiClientInterface, and expect users to choose client library and select/create adapter?
Or maybe leave no-client version as default and add --library=httplug?

Copy link
Contributor

Choose a reason for hiding this comment

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

Here's a suggested flow which makes sense to me:

  1. generate no implementation dependency by default, this will generate a "clean" version, add additional info / sample code on how to inject own HTTP client
  2. generate an additional class if --library=httplug is provided, this version is basically 1) with an additional item in composer.json and a HTTP client pre-injected for you (so, you can still inject another client yourself if you don't want to use the additional class, it just doesn't install a depenency you might not want by default)

We might make 2) the default to keep BC though.

Copy link
Contributor

Choose a reason for hiding this comment

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

@wing328 sounds good to me, documentation should note how to create a "bare" version, for example --library=psr7.

Copy link
Contributor Author

@baartosz baartosz Mar 29, 2017

Choose a reason for hiding this comment

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

Settled then. I'll update this PR soon with default version (with guzzle as its easier to use than httplug) and add --library=psr7 later as separate feature.

Copy link
Contributor

Choose a reason for hiding this comment

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

@baartosz Guzzle is a better choice as you don't need an abstraction since PSR7 is your preferred abstraction, no need for an abstraction over an abstraction.

Copy link

Choose a reason for hiding this comment

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

@baartosz want to test&adopt your httplug client + guzzle. Good time to make it a try? would I wait a little for your " I'll update this PR soon with default version.."

thx a lot for your work

Copy link
Contributor Author

@baartosz baartosz Mar 30, 2017

Choose a reason for hiding this comment

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

@richhl guzzle6-only version is almost ready, it will be better to wait for it instead of reviewing and re-reviewing later.

@baartosz
Copy link
Contributor Author

baartosz commented Mar 30, 2017

@wing328

Currently readme.md says that client works with php 5.4 which is not maintained for 1,5 years
http://php.net/supported-versions.php

Should default version work with
guzzle 5 which is not psr7-compatible to still have it working with php>=5.4?
or use guzzle 6 psr compatible but requiring php>=5.5 and drop 5.4 support?

@arnested
Copy link
Contributor

I would say go for as new a version as needed. For this new way of doing it I don't see a need to forcefully stay behind on old PHP versions.

@wing328
Copy link
Contributor

wing328 commented Mar 30, 2017

Agreed with @arnested. @baartosz please feel free to drop 5.4 support.

If someone needs the PHP API client to work with PHP 5.4, they can always use Swagger Codegen v2.2.2 to generate the client.

@@ -123,51 +109,6 @@ class Configuration
protected $tempFolderPath;

/**
* Indicates if SSL verification should be enabled or disabled.
Copy link

@richhl richhl Mar 30, 2017 via email

Choose a reason for hiding this comment

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

@baartosz
Copy link
Contributor Author

Updated, rebased, tested with php 7 and 5.5, ready to review.
Httplug removed, guzzle6 added, required php increased to 5.5.

Unfortunately python test suite is breaking build for some reason.

[INFO] Python Swagger Petstore Client .................... FAILURE [20.635s]

@wing328
Copy link
Contributor

wing328 commented Mar 30, 2017

@baartosz don't worry about the Python test failure. I've fixed it in the master. (I'll run some tests later and let you know if I've any feedback)

@richhl
Copy link

richhl commented Mar 31, 2017 via email

@wing328
Copy link
Contributor

wing328 commented Mar 31, 2017

@richhl here are the steps to test it

git checkout -b baartosz-php_httplug2 2.3.0
git pull https://github.com/baartosz/swagger-codegen.git php_httplug2
mvn clean package

Then you can use the JAR to generate PHP API client by providing a spec.

@baartosz baartosz changed the title Php client using httplug & psr7 instead of curl Php client using guzzle6 & psr7 instead of curl Mar 31, 2017
@wing328
Copy link
Contributor

wing328 commented Apr 1, 2017

The Travis CI tests passed: https://travis-ci.org/swagger-api/swagger-codegen/builds/217127129

@wing328
Copy link
Contributor

wing328 commented Apr 1, 2017

I used PHP CodeSniffer to inspect the code and found some enhancements (code format) we can make to the PHP API client (this PR and master). I'll create a separate task for tracking.

@wing328 wing328 mentioned this pull request Apr 1, 2017
1 task
@baartosz
Copy link
Contributor Author

baartosz commented Apr 3, 2017

just a rebase to solve conflicts

@wing328 wing328 merged commit 2315ef2 into swagger-api:2.3.0 Apr 3, 2017
@wing328
Copy link
Contributor

wing328 commented Apr 3, 2017

@baartosz PR merged into 2.3.0. Thanks for the huge enhancement!

I'm sure the community appreciates your effort.

@dkarlovi
Copy link
Contributor

dkarlovi commented Apr 3, 2017

@baartosz awesome work!

@baartosz
Copy link
Contributor Author

baartosz commented Apr 3, 2017

@dkarlovi @wing328 that was quick. Did you even review the code? ;)

Thanks for your time and input!

@richhl
Copy link

richhl commented Apr 3, 2017

don't worry @baartosz! hundred of eyes and hands are ready now to test and contribute changes if any.

we expect to test this week and next. will get in touch. thx 4 your work

@wing328
Copy link
Contributor

wing328 commented Apr 3, 2017

@baartosz I did review the code and play around with it over the weekend.

Like any other generators, I would expect it to improve over time thanks to the vibrant community.

@wing328 wing328 changed the title Php client using guzzle6 & psr7 instead of curl [PHP] using guzzle6 & psr7 instead of curl Apr 4, 2017
@wing328 wing328 changed the title [PHP] using guzzle6 & psr7 instead of curl [PHP] API client using guzzle6 & psr7 instead of curl Apr 4, 2017
@wing328
Copy link
Contributor

wing328 commented May 2, 2017

FYI. Updated README to include @baartosz as the template owner of PHP Guzzle

@Robert430404
Copy link

Hello,

Not sure if this is the right place, but I'm wanting to use the template specified in this PR and I can't find any documentation on how I go about using it. If you guys could point me in the right direction, I would really appreciate it!

Thanks in advance,
Robert

@wing328
Copy link
Contributor

wing328 commented May 19, 2017

@Robert430404 Please open a new issue with the question instead.

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.

None yet

6 participants