Giter Site home page Giter Site logo

retrofit-php's People

Contributors

gounlaf avatar jdreesen avatar mattjanssen avatar mloberg avatar natebrunette avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

retrofit-php's Issues

Add annotations

Cookie
Cookies
CookieMap
PartMap
Field
FieldMap
HeaderMap

Add support for JsonSerializable

The @Body annotation should have an option jsonSerializable, which will json encode the object before attempting to serialize it.

Not working for symfony 2.7

Since the package is relying on specific versions of some components, (symfony/console, symfony/filesystem) it's not working on symfony 2.7

Bump JMS Serializer to Latest Release

This flies directly in the face of #22, but it'd be great to see the composer dependency for jms/serializer updated to ~1.0. Not sure what implications that has on the library, but suspecting that's a quicker thing to investigate than adding in all the adapters for serializer behavior that the other ticket will require.

Is it possible to use lambdas as a callbacks instead of Callback object?

I found that retrofit-php supports asynchronous calls but as callbacks it requires an instance of \Tebru\Retrofit\Http\Callback Such a callback is OK in Java since it supports lambdas only starting from 8 version but it supports anonymous classes. In php though it's not OK because php supports lambdas very long time but it supports anonymous classes only starting from php7. So I need to create a class which implements Callback interface somewhere else then create an instance of this class and only after that pass it to my client function. It's very inconvenient. So I wonder if it possible to use success/failure lambdas to handle response asynchronously?

Check for optional body

Through fortuitous type changing when serializing null, the body gets passed to Guzzle as false instead of null and guzzle only does a falsey check for the body. It would be better to do a check if body is null and not attempt serialization at all.

Dynamic Headers

It would be useful to set headers using logic instead of just being a simple string. One use case of this is to set X-Forwarded-For to the end user's IP.

Using @ResponseBody with arrays?

Hello, I'm trying to use the ResponseBody annotation to transform a response that returns an array of objects. Does the annotation support array syntax? I was expecting to use something like…

@ResponseBody("MyNamespace/MyClass[]")

…but I'm getting a ResponseHandlingFailedException: "Retrofit: Could not convert response body" exception.

Refactor generation handlers?

Rather than using a HandlerFactory with specific methods for creating each individual handler type, have you considered either just creating the handlers within the DynamoMethodListener directly or maybe modifying the HandlerFactory to return an array of handlers? Right now the HandlerFactory doesn't provide a ton of value (aside from potentially mock-ability within tests) and is IMO too aware of all of the possible implementations of handlers.

Current Implementation

$handlers = [
    $this->handlerFactory->baseUrl($methodModel, $methodBodyBuilder, $annotations),
    $this->handlerFactory->serializationContext($methodModel, $methodBodyBuilder, $annotations),
    $this->handlerFactory->requestUrl($methodModel, $methodBodyBuilder, $annotations),
    $this->handlerFactory->requestHeader($methodModel, $methodBodyBuilder, $annotations),
    $this->handlerFactory->requestBody($methodModel, $methodBodyBuilder, $annotations),
    $this->handlerFactory->returns($methodModel, $methodBodyBuilder, $annotations),
    $this->handlerFactory->asyncCallback($methodModel, $methodBodyBuilder, $annotations),
];

Option A

Create the handlers inline. This would remove the necessity of the factory entirely.

$handlers = [
    new BaseUrlHandler($methodModel, $methodBodyBuilder, $annotations),
    new SerializationContextHandler($methodModel, $methodBodyBuilder, $annotations),
    new RequestUrlHandler($methodModel, $methodBodyBuilder, $annotations),
    new RequestHeaderHandler($methodModel, $methodBodyBuilder, $annotations),
    new RequestBodyHandler($methodModel, $methodBodyBuilder, $annotations),
    new ReturnHandler($methodModel, $methodBodyBuilder, $annotations),
    new AsyncHandler($methodModel, $methodBodyBuilder, $annotations),
];

Option B

Make the handler factory responsible for creating the handlers. With this approach, the listener doesn't know or care what type of handlers are handling the class.

$handlers = $this->handlerFactory->create($methodModel, $methodBodyBuilder, $annotations);

Option C

Allow for stateless handlers. This would be quite a bit more of a refactor, but you could change the abstract Handler into a HandlerInterface...

<?php

namespace Tebru\Retrofit\Generation\Handler;

interface HandlerInterface
{
    /**
     * @param MethodModel $methodModel
     * @param MethodBodyBuilder $methodBodyBuilder
     * @param AnnotationCollection $annotations
     */
    public function handle(MethodModel $methodModel, MethodBodyBuilder $methodBodyBuilder, AnnotationCollection $annotations);
}

Then you could inject an array of HandlerInterface's into your listener and delegate accordingly.

<?php

namespace Tebru\Retrofit\Generation\Listener;

use Tebru\Dynamo\Event\MethodEvent;
use Tebru\Retrofit\Generation\Builder\Factory\MethodBodyBuilderFactory;
use Tebru\Retrofit\Generation\Handler\HandlerInterface;

class DynamoMethodListener
{
    /**
     * @var HandlerInterface[]
     */
    private $handlers;

    /**
     * Creates a new method body builder
     *
     * @var MethodBodyBuilderFactory
     */
    private $methodBodyBuilderFactory;

    /**
     * Constructor
     *
     * @param HandlerInterface[] $handlers
     * @param MethodBodyBuilderFactory $methodBodyBuilderFactory
     */
    public function __construct(array $handlers, MethodBodyBuilderFactory $methodBodyBuilderFactory)
    {
        $this->handlers = $handlers;
        $this->methodBodyBuilderFactory = $methodBodyBuilderFactory;
    }

    /**
     * Handler the event
     *
     * @param MethodEvent $event
     */
    public function __invoke(MethodEvent $event)
    {
        $methodModel = $event->getMethodModel();
        $annotations = $event->getAnnotationCollection();
        $methodBodyBuilder = $this->methodBodyBuilderFactory->make();

        foreach ($this->handlers as $handler) {
            $handler->handle($methodModel, $methodBodyBuilder, $annotations);
        }

        $body = $methodBodyBuilder->build();
        $methodModel->setBody($body);
    }
}

Option D

Create an aggregate method handler. This wouldn't require a major refactor, but could help keep the method listener simpler. The listener would create a single handler, which would be responsible for creating and calling the other handlers. I haven't fully thought this one through yet...

<?php

namespace Tebru\Retrofit\Generation\Handler;

class MethodHandler
{
    /**
     * @var Handler[]
     */
    private $handlers;

    /**
     * @param MethodModel $methodModel
     * @param MethodBodyBuilder $methodBodyBuilder
     * @param AnnotationCollection $annotations
     */
    public function __construct(MethodModel $methodModel, MethodBodyBuilder $methodBodyBuilder, AnnotationCollection $annotations);
    {
        $this->handlers = [
            new BaseUrlHandler($methodModel, $methodBodyBuilder, $annotations),
            new SerializationContextHandler($methodModel, $methodBodyBuilder, $annotations),
            new RequestUrlHandler($methodModel, $methodBodyBuilder, $annotations),
            new RequestHeaderHandler($methodModel, $methodBodyBuilder, $annotations),
            new RequestBodyHandler($methodModel, $methodBodyBuilder, $annotations),
            new ReturnHandler($methodModel, $methodBodyBuilder, $annotations),
            new AsyncHandler($methodModel, $methodBodyBuilder, $annotations),
        ];
    }

    /**
     * @inheritdoc
     */
    public function handle()
    {
        foreach ($this->handlers as $handler) {
            $handler->handle();
        }
    }
}
<?php

namespace Tebru\Retrofit\Generation\Listener;

use Tebru\Dynamo\Event\MethodEvent;
use Tebru\Retrofit\Generation\Builder\Factory\MethodBodyBuilderFactory;

class DynamoMethodListener
{
    /**
     * Creates a new method body builder
     *
     * @var MethodBodyBuilderFactory
     */
    private $methodBodyBuilderFactory;

    /**
     * Constructor
     *
     * @param MethodBodyBuilderFactory $methodBodyBuilderFactory
     */
    public function __construct(MethodBodyBuilderFactory $methodBodyBuilderFactory)
    {
        $this->methodBodyBuilderFactory = $methodBodyBuilderFactory;
    }

    /**
     * Handler the event
     *
     * @param MethodEvent $event
     */
    public function __invoke(MethodEvent $event)
    {
        $methodModel = $event->getMethodModel();
        $annotations = $event->getAnnotationCollection();
        $methodBodyBuilder = $this->methodBodyBuilderFactory->make();

        $handler = new MethodHandler($methodModel, $methodBodyBuilder, $annotations);
        $handler->handle();

        $body = $methodBodyBuilder->build();
        $methodModel->setBody($body);
    }
}

PHP 8 annotations (attributes)

Hello,
firstly thanks for a great job with this java-backport lib.
You have any plans to migrate doctrine annotations to PHP native attributes?

Support for optional query parameters

Currently, all @query parameters are sent to the server, regardless of if they are required or not. It would be nice to be able to specify some @query annotations as optional so they are not sent to the server if they are null.

Fix how QueryMap works

It appears that query map is not correctly creating a query string. Figure out how to correctly merge into query params.

PhpParser/Parser cannot be instatiated

PhpParser/Parser changed to an interface in nikic/php-parser: ^2.0 causing:

Cannot instantiate interface PhpParser\Parser in /bla/bla/bla/vendor/tebru/retrofit-php/src/Generation/Printer/ArrayPrinter.php on line 41

I think changing:

if (null === $parser) {
    $parser = new Parser(new Lexer());
}

To either using the PhpParser factory instead:

use PhpParser\ParserFactory;
$parser = (new ParserFactory)->create(ParserFactory::PREFER_PHP7);

or always passing in the parser argument to use in the ArrayPrintyer.

A temporary workaround for this is to (i think) install tebru/dyanmo:0.3.1:

composer require tebru/dyanmo:0.3.1

Had to call `AnnotationRegistry::registerLoader()` manually

For some reason every time the annotations were loaded while my cache was empty, they worked. Perhaps because my app was also loading @Route annotations at the same time.

But once the cache was warmed, every subsequent load failed:

AnnotationException::semanticalError('The annotation "@Tebru\\Retrofit\\Annotation\\GET" in method App\\Azure\\AzureSdkInterface::listDeployments() does not exist, or could not be auto-loaded.')
in DocParser.php line 734

I added this to my index.php and bin/console to make it work again:

$loader = require dirname(__DIR__).'/vendor/autoload.php';
AnnotationRegistry::registerLoader([$loader, 'loadClass']);

Guzzle 5 Events Not Working

The Guzzle 5 event emitter doesn't seem to be working in the new (2.x) version of Retrofit.

In some very basic debugging, I found that the Guzzle transaction was not using the EventEmitter that was attached to the Client.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.