Comments (14)
Hi,
Just to confirm I had similar issues with setting the base uri. Finally found this thread and made it work with:
$plugin = new AddHostPlugin(new Uri('https://foo.bar/'), ['replace' => true,]);
$pluginClient = new PluginClient( HttpClientDiscovery::find(), [$plugin] );
$apiClient = Client::create($pluginClient);
but it should be somehow configurable, or at least covered in install docs.
from janephp.
I handle this kind of need by providing my own HTTPlug client to the created Client.
Example with Symfony Httplug:
httplug:
clients:
api_client_with_host:
factory: 'httplug.factory.guzzle6'
plugins:
- add_host:
host: 'acc-preprod-staging.com'
replace: true
services:
MyGeneratedBlaBla\Resource\MyResource:
arguments:
- '@httplug.client.api_client_with_host'
- '@httplug.message_factory'
- '@foobar.chained_serializer'
At the end, it's only about being able to build the proper HTTPlug client. The fact I use Symfony has nothing to do with it.
You could try this:
$plugin = new AddHostPlugin('domain.com'), [
'replace' => true,
]));
$pluginClient = new PluginClient(
HttpClientDiscovery::find(),
[$plugin]
);
from janephp.
Thank you for your reply! It's not completely clear to me though. I am using Symfony as well, but as you say, that does not affect anything.
Creating the PluginClient()
which includes a HostPlugin
is not a problem. Passing that client to the Jane Client
(class Client extends \Jane\OpenApiRuntime\Client\Psr7HttplugClient
) is where the problem lies.
A part of the Client class is as follows:
class Client extends \Jane\OpenApiRuntime\Client\Psr7HttplugClient
{
public static function create($httpClient = null)
{
if (null === $httpClient) {
$httpClient = \Http\Discovery\HttpClientDiscovery::find();
$plugins = array();
$uri = \Http\Discovery\UriFactoryDiscovery::find()->createUri('http://example.org/some/endpoint');
$plugins[] = new \Http\Client\Common\Plugin\AddPathPlugin($uri);
$plugins[] = new \Http\Client\Common\Plugin\AddHostPlugin($uri);
$httpClient = new \Http\Client\Common\PluginClient($httpClient, $plugins);
}
$messageFactory = \Http\Discovery\MessageFactoryDiscovery::find();
$streamFactory = \Http\Discovery\StreamFactoryDiscovery::find();
$serializer = new \Symfony\Component\Serializer\Serializer(...);
return new static($httpClient, $messageFactory, $serializer, $streamFactory);
}
}
(this is the case when both basePath
and host
are provided; when host
is omitted, the AddHostPlugin()
call is dropped)
If I create the PluginClient
and pass it to the method, the whole logic if appending the path to the client is skipped. However, this is the part that I want executed, because my PluginClient
only contains information about the host
, not the basePath
.
from janephp.
I had more or less the same problem with our Slack client so I had to manually readd this logic in our own client, see https://github.com/jolicode/slack-php-api/blob/master/src/ClientFactory.php#L33-L42 for an example 😉
from janephp.
This requires you to know the host and path to the service though, doesn't it? This does not allow you to change the URL based on the environment you are runnign in. I am trying to have the basePath
part of the Client configuration stored in the yaml spec and the host
in a configuration file elsewhere.
I could read both those files and then construct the Client
by hand, but that seems clunky and redundant, especially since Jane already reads the yaml spec file.
from janephp.
You could do what @pyrech have done but instead of hardcoding the hostname passing it to the method as a parameter :
public static function create(string $host, HttpClient $httpClient = null)
Then on symfony you can use env parameters to change the URL passed to this method.
Normally you would use this method (static create) only on prototyping / testing, otherwise i recommend you to create the services chain by using DIC of symfony.
from janephp.
I recommend you to create the services chain by using DIC of symfony
Good to know. I think it's worth documenting in some "best practices" way.
Pardon my ignorance, but I am still not getting it.
First, in order to change the static create()
function I would have to manually edit the generated code. That would get overwritten whenever the underlying spec changes. I want to be able to re-generate the code and use it with no manual edits on my part.
Second, let's say I don't use the create()
factory method at all. I construct the HttpClient
object myself and pass it into the generated Client
. It has to already have both host
and basePath
plugins/properties provided, correct? And I do not see a way to be able to read the basePath
property from the generated code. Here I am trying to avoid having to re-read and parse the spec file.
Are my assumptions correct?
from janephp.
First, in order to change the static create() function I would have to manually edit the generated code. That would get overwritten whenever the underlying spec changes. I want to be able to re-generate the code and use it with no manual edits on my part.
You should not edit the generated code but instead create your own class which can extend the existing one and which have the static method.
Second, let's say I don't use the create() factory method at all. I construct the HttpClient object myself and pass it into the generated Client. It has to already have both host and basePath plugins/properties provided, correct? And I do not see a way to be able to read the basePath property from the generated code. Here I am trying to avoid having to re-read and parse the spec file.
There is no way to read it without parsing the spec file, you are correct.
It may be something to add (like having some methods returning base path / etc ...) but AFAIK updating the host in the spec is very rare so just writing it down in your env without parsing it is fine most of the time.
We use a lot Jane in our projects and we never trust those value and instead use our own configured by the DIC of Symfony.
from janephp.
It may be something to add (like having some methods returning base path / etc ...) but AFAIK updating the host in the spec is very rare so just writing it down in your env without parsing it is fine most of the time.
I agree. We want the host to be defined in our parameters, so that we can control where requests are being made in which environment.
We use a lot Jane in our projects and we never trust those value and instead use our own configured by the DIC of Symfony.
We use the spec files provided to use by a third party with which we integrate. The base path should not change much, but if it did, I would expect that change to be in the provider's jurisdiction. And as such, it makes sense to me to "trust" that value. Maybe not the host
, which can be behind proxies or something, but the basePath
seems that it should be "stable".
In any case, to conclude - I will define both host
and basePath
in config files and fetch from DIC. Feature request would be storing the parsed basePath
(and maybe host
as well) in a protected member variable instead of hardcoding that string in the create()
method.
I can make a MR if I find some free time. Thank you!
from janephp.
Actually you can set it through the servers
field in your OpenApi spec, see https://github.com/janephp/janephp/blob/master/src/OpenApi/Tests/fixtures/client-psr18/swagger.json#L15-L22 for an example (only one url
is needed to generate it)
If you have multiple server urls, there is actually no way to set it through OpenApi spec, so you have to use your own plugin 👍
from janephp.
Hm, I am not in control of the json openapi file, I just read it :/
from janephp.
So you have to use the plugin like you said in your last comment.
About docs, we use plugins from php-http
, you can see their docs here: http://docs.php-http.org/en/latest/plugins/index.html
from janephp.
Actually you can set it through the
servers
field in your OpenApi spec, see https://github.com/janephp/janephp/blob/master/src/OpenApi/Tests/fixtures/client-psr18/swagger.json#L15-L22 for an example (only oneurl
is needed to generate it)If you have multiple server urls, there is actually no way to set it through OpenApi spec, so you have to use your own plugin +1
It seems to me like the OpenAPI spec does support multiple servers listed, or am I misunderstanding something?
from janephp.
It seems to me like the OpenAPI spec does support multiple servers listed, or am I misunderstanding something?
Sorry, I was talking about Jane support of servers
field, since we don't have a way to know which server we should use, we only take the first one.
I'm gonna close this issue since it's an old one and doesn't have a clear meaning actually, feel free to open a new one if needed.
from janephp.
Related Issues (20)
- ObjectTransformer is not available when custom MapperConfigurationInterface is processed HOT 2
- [Automapper] private properties in constructor are not mapped HOT 1
- [Automapper] problem when getter type is different from property type HOT 1
- Denormalizing invalid date or datetime results in TypeError HOT 1
- Allow openapi-file to be an URL
- BadRequestException is not marked abstract
- OAS 3.1: Declaring type as array results in TypeError (for nullable types) HOT 1
- Classes referenced as strings instead of via ::class
- Missing "default" response models when using "whitelisted-paths"
- Empty String for Date
- Warning: Undefined array key "" produces an Uncaught TypeError
- Content-Type `application/json;charset=UTF-8` is not serialized/deserialized as JSON
- Error in BodyParameterGenerator::convertParameterType when generating HOT 1
- PHP Warning: Undefined array key "object" in /home/xxx/projects/camunda-api-client/vendor/jane-php/open-api-3/Generator/Parameter/NonBodyParameterGenerator.php on line 197
- Bump symfony/serializer to 7.0 in jane-php/open-api-runtime HOT 1
- Consider allowing int for `number` type
- Direct dependency php-http/message-factory is abandoned HOT 2
- Bump nikic/php-parser to latest version HOT 1
- Jane 7.6.0 relies on Symfony 7.0? HOT 1
- Wrong type for array
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from janephp.