Giter VIP home page Giter VIP logo

webservice's Introduction

Webservice

Build Status Coverage Total Downloads License

Bringing the power of the CakePHP ORM to your favourite webservices.

Install

Using Composer:

composer require muffin/webservice

You then need to load the plugin. You can use the shell command:

bin/cake plugin load Muffin/Webservice

Usage

Datasource Configuration

In your app.php, add a new webservice config under Datasources:

    'Datasources' => [
        // Other db config here
        'webservice' => [
            'className' => \Muffin\Webservice\Datasource\Connection::class,
            'service' => 'Articles',
            // Any additional keys will be set as Driver's config.
        ],
    ],

If you are making a plugin then conventionally the datasource config key name should be underscored version of plugin name.

As an ORM

Create driver

<?php
namespace App\Webservice\Driver;

use Cake\Http\Client;
use Muffin\Webservice\Driver\AbstractDriver;

class Articles extends AbstractDriver
{
    /**
     * Initialize is used to easily extend the constructor.
     */
    public function initialize(): void
    {
        $this->setClient(new Client([
            'host' => 'example.com'
        ]));
    }
}

Create a webservice

<?php
namespace App\Webservice;

use Muffin\Webservice\Datasource\Query;
use Muffin\Webservice\Datasource\ResultSet;
use Muffin\Webservice\Webservice\Webservice;

class ArticlesWebservice extends Webservice
{
    /**
     * Executes a query with the read action using the Cake HTTP Client
     */
    protected function _executeReadQuery(Query $query, array $options = [])
    {
        $response = $this->getDriver()->getClient()->get('/articles.json');

        if (!$response->isOk()) {
            return false;
        }

        $resources = $this->_transformResults($query->endpoint(), $response->json['articles']);

        return new ResultSet($resources, count($resources));
    }
}

Create an endpoint (optional)

<?php
namespace App\Model\Endpoint;

use Muffin\Webservice\Model\Endpoint;

class ArticlesEndpoint extends Endpoint
{
}

Create a resource (optional)

<?php
namespace App\Model\Resource;

use Muffin\Webservice\Model\Resource;

class Article extends Resource
{
}

Use it

<?php
namespace App\Controller;

use Muffin\Webservice\Model\EndpointLocator;

class ArticlesController extends AppController
{
    // Either set the default model type to "Endpoint" or explicitly specify
    // model type in loadModel() call as shown below.
    protected $_modelType = 'Endpoint';

    public function index()
    {
        // This is required only if you haven't set `$_modelType` property to
        // "Endpoint" as shown above.
        $this->loadModel('Articles', 'Endpoint');

        $articles = $this->Articles->find();
    }
}

As base for a driver

You can also use this plugin as a base to a separate plugin or to manage custom webservice drivers connections.

Until official documentation is written, David Yell wrote a good post to get you started.

Implementations of webservices

As an ORM

The following plugins use the Webservice ORM to give you easy access to all kinds of webservices:

  • GitHub plugin - Provides access to the GitHub REST APIs.
  • NS plugin - Provides access to the NS (Nederlandse Spoorwegen) APIs.
  • Stagemarkt plugin - Provides access to the SBB Stagemarkt REST APIs.
  • Twitter plugin - Provides access to the Twitter REST and streaming APIs.

As a driver

The following plugins implement a Webservice driver with their own methods:

Patches & Features

  • Fork
  • Mod, fix
  • Test - this is important, so it's not unintentionally broken
  • Commit - do not mess with license, todo, version, etc. (if you do change any, bump them into commits of their own that I can ignore when I pull)
  • Pull request - bonus point for topic branches

To ensure your PRs are considered for upstream, you MUST follow the CakePHP coding standards.

Bugs & Feedback

http://github.com/usemuffin/webservice/issues

License

Copyright (c) 2015-Present, [Use Muffin] and licensed under The MIT License.

webservice's People

Contributors

admad avatar asgraf avatar bancer avatar ceeram avatar davidyell avatar drmonkeyninja avatar jadb avatar marlinc avatar nic0tin avatar othercorey avatar saeideng 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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

webservice's Issues

Initial release

Please can you push a release for this, as the codebase hasn't changed at all in a few months, a nice 0.0.1 would be ace so I don't see dev-master lurking in my composer file.

Thanks!

How to use multiple nested resources?

My setup

I have configured the driver and the webservice class, with my resources and endpoints. Recently we changed our api, so that we have types in the url.

An example of this would be

I have, in my Webservice class, configured the nested resources as follows.

public function initialize()
{
    parent::initialize();

    $this->addNestedResource(Configure::read('dsapi.url') . 'packages/:type', ['type']);
    $this->addNestedResource(Configure::read('dsapi.url') . 'providers/:type', ['type']);
}

What is happening?

I cannot access my providers endpoint, because the requests are being redirected to the packages endpoint.

What am I expecting to happen

I'd expect that the nested resources would co-habit and I'd be able to access both endpoints, with their various types.

Sidestep

I can access one or the other by commenting out one of the lines, but not both at the same time.

Query->count() raises an error if webservice->execute() returns false

The Query->count() contains the following line:

return $this->__resultSet->total();

But the Query->_execute() method assigns directly the result of the webservice request to $this->__resultSet without checking the returned type:

return $this->__resultSet = $this->_webservice->execute($this);

and according to the doc, the WebserviceInterface->execute() function may return a ResultSet, but also an integer or a boolean:

@return \Muffin\Webservice\ResultSet|int|bool

Therefore for example if the webservice request fails and returns false, $this->__resultSet does not have any total() method and an error is raised.

A solution could be :

if(method_exists($this->__resultSet, 'total')) {
    return $this->__resultSet->total();
} else {
    return false;
}

or

if(is_a($this->__resultSet, '\Cake\Datasource\ResultSetInterface')) {
    return $this->__resultSet->total();
} else {
    return false;
}

RFC: 2.0.0 Roadmap

I wanted to quickly make some notes about things which I think could be worked on for the next major release of the plugin. This is a quick list and by no means exhaustive. Any suggestions are welcome

  • CakePHP 3.5 support. Is it worth continuing work in the existing 3.4-test branch? Bump up to CakePHP 3.6
  • Where appropriate refactor mixed mode methods, such as Endpoint::endpoint() and Endpoint::alias() to getters and setters
  • Tidy up the api to remove confusing method names. Eg, Endpoint::endpoint and Endpoint::endpoint()
  • Upgrade to usage of setConfig() and getConfig()
  • Bump code sniffer version and fix any warnings
  • Implement the new setAlias() and getAlias() methods which are now part of the core RepositoryInterface into the Endpoints
  • Replace the useless {@inheritDoc} doc blocks with actual doc blocks
  • Move the AbstractDriver class into the Driver folder and update it's namespace
  • Typehint where appropriate such as Endpoint::webservice()
  • Add phpstan, with a script for basic support such as level 2
  • Bump phpunit to 7.x and update the test suite
  • Fix the FixtureListener in the phpunit.xml file as PHPUnit 7.x doesn't have the BaseListener class
  • If no results are found, the returned total should be zero #44
  • Refactor Schema::options()
  • Refactor Schema::columnType()
  • Deprecate ControllerEndpointFilter since dispatch filters are deprecated in Cake 3.6 and add corresponding middleware instead. #64
  • Deprecate the EndpointRegistry, as TableRegistry has been deprecated #69
  • Fix the Test boostraps use of deprecated DispatcherFactory #67
  • Using Query::repository() as getter is deprecated. Use getRepository() instead. Seems mostly to be in the tests
  • Update the deprecated TypeMap() calls
  • Adding pagination support, ref #42 #43 Moved to post 2.0.0 release.
  • Re-name some variables to better differentiate between strings and instances
  • Update the Readme to show the new api

Complete testing for 2.0 release

I am creating a ticket for myself to polish off the final few bits that might be needed to get the plugin to a stage where we can issue a release.

I have created an example application for testing. https://github.com/davidyell/Example-MuffinWebservice

@ADmad If you can think of anything else, or would like to do some testing yourself, please let me know if there are outstanding items and I will get them done.

I'm keen to get 2.0 released, so I can start working on the Pagination and Form Context

Endpoint returning an image

Has anyone has any luck with an endpoint that returns an image?
I get the error:

Argument 2 passed to Muffin\Webservice\Webservice\Webservice::_transformResource() must be of the type array, null given, called in .../vendor/muffin/webservice/src/Webservice/Webservice.php

Trouble with Usage Example

I'm working through the usage example in the readme and have stumbled across an issue that's probably simple, but I'm stuck on.

I'm struggling with the example Webservice.

<?php

namespace App\Webservice;

use Cake\Network\Http\Client;
use Muffin\Webservice\Query;
use Muffin\Webservice\Webservice\Webservice;

class ArticlesWebservice extends Webservice
{

    /**
     * {@inheritDoc}
     */
    protected function _executeReadQuery(Query $query, array $options = [])
    {
        $response = $this->driver()->client()->get('/articles.json');

        if (!$response->isOk()) {
            return false;
        }

        $resources = $this->_transformResults($query->endpoint(), $response->json['articles']);

        return new ResultSet($resources, count($resources));
    }
}

Running this code I'm seeing an "Class 'App\Webservice\ResultSet' not found" error.

What class/file/source does new ResultSet($resources, count($resources)); come from?

I've looked through the included classes and can't seem to find it. So, I assumed maybe the example just forgot use Cake\ORM\ResultSet. Looking at the spec for Cake\ORM\ResultSet the input variables are a Cake\ORM\Query and Cake\Database\StatementInterface. The variables passed to ResultSet in the example are not those types.

What am I missing here?

Thanks!

No way to clear the Endpoint registry

There seems to be no way to clear the Endpoint registry. This means if you're testing with lots of test cases, there is no way to reset the registry.

Is it possible to use the FormHelper ?

Hi,

I'm trying to use your very promising plugin to implement some CRUD on a custom webservice but I'm facing a problem when creating a form in the view. The FormHelper fails to create a context based on the Resource given to the Form->create($resource) method.

I noticed the form-context branch of the project, and I guess this has something to do with that, but what's the state of these branches ? Is it already possible to use the FormHelper ? If not what's the best alternative ? Modelless forms ?

Thanks a lot.

Missing endpoint exception

What I did

I have created my ExamplesTable, but no endpoint class.

$this->modelFactory('Endpoint', [EndpointRegistry::class, 'get']);
$endpoint = $this->loadModel('Examples', 'Endpoint');

What happened

Exception: The datasource configuration "supply" was not found. in [/Users/david/Sites/Gaia/vendor/cakephp/cakephp/src/Datasource/ConnectionManager.php, line 196]

What I expected to happen

I would expect that a MissingEndpoint exception, or similar, telling me that the Endpoint class is missing or can't be loaded. Rather than the method getting all the way to the ConnectionManager.

Embedded resources in api result

Hi,

I'm trying to understand if it is possible to get add related resources to response.

I do a request to the API to get messages, the response contains an array of the user that it posted id. simple example:

{
	"id": "36f23f2bc90d35f0",
	"created": "2020-06-24T09:27:40.217+00:00",
	"body": "This is a message",
	"user": {
		"id": 1,
		"name": "jan",
		"email": "[email protected]"
	}
}

is it possible some way that the user array transforms to a User resource inside the Message Resource? At the moment when I do $this->_transformResults($query->endpoint(), $messages); it will returns a MessageResource with an array instead of user resource.

BUILD_VALIDATOR_EVENT class constant

In CakePHP 3.5 classes using ValidatorAwareTrait must have BUILD_VALIDATOR_EVENT constant defined. In this case Muffin\Webservice\Model\Endpoint class. Currently causing "Undefined class constant 'BUILD_VALIDATOR_EVENT'" exception.

Webservice twitter does not implement isQueryLoggingEnabled

Webservice twitter does not implement isQueryLoggingEnabled
Muffin\Webservice\Exception\UnimplementedWebserviceMethodException

vendor/cakephp/debug_kit/src/Panel/SqlLogPanel.php triggers this in the if ($connection->isQueryLoggingEnabled()) { call.
With CakePHP 3.7+

RFC, Confusing method naming

What I did

I was writing my Webservice class, and wanted to get the endpoint to add to my url, in the _executeReadQuery method.

$apiUrl = 'https://example.com/api/v1/';

/* @var $endpoint \Muffin\Webservice\Model\Endpoint */
$endpoint = $query->repository()->endpoint();

$endpointUrl = $apiUrl . $endpoint->endpoint();

What's confusing

I found calling endpoint() on the repository returning an Endpoint class instance, yet, calling endpoint() on the Endpoint, returned a string.

Solutions

I would probably change the names to be more descriptive of what they're actually doing. I'm easy on the use of getter/setters, but I'd prefer they were used.

$apiUrl = 'https://example.com/api/v1/';

/* @var $endpoint \Muffin\Webservice\Model\Endpoint */
$endpoint = $query->repository()->getEndpoint();

$endpointUrl = $apiUrl . $endpoint->getName();

Pull request

I can obviously submit a pull request for this, but as it would break BC, I would like some input from other people. As it would probably mean a new major release as well.

Missing type casting

The \Muffin\Webservice\Datasource\Marshaller currently ignores the existence of /src/Model/Endpoint/Schema/****Schema classes, does not build a property map, and never calls TypeInterface::marshal()

Additionally \Muffin\Webservice\Webservice\Webservice::_transformResource() never calls TypeInterface::toPHP()

Tested on version 3.0.0

Edit object

I've error to match the edit object. Cake 3.6 try to find

SQLSTATE[42S02]: Base table or view not found: 1146 Table 'xxx.resources' doesn't exist

This is the code under UsersWebservice

            $resource = $this->_transformResource(new UsersEndpoint(), $resultArray);
             return new ResultSet([$resource], 1);

and returning this object format

Muffin\Webservice\Model\Resource Object
(
    [id] => 3
    [username] => abc
    [fullname] => ABC
    [email] => [email protected]
    [group_id] => 1
    [tenant_id] => 1
    [team_id] => 0
    [tenant] => stdClass Object
        (
            [id] => 1
            [code] => xxx
            [name] => xxx
            [active] => 1
            [created] => 2018-11-08T13:00:00
            [modified] => 2018-11-08T13:00:00
        )

    [group] => stdClass Object
        (
            [id] => 1
            [code] => SA
            [description] => Super Admin
            [tenant_id] => 0
        )

    [[new]] => 

Any suggestion

explode() expects parameter 2 to be string, null given

So, I'm trying out Webservice plugin for Cake 4.

I've created a Driver and using as a Driver works just fine.

But, when I try to use as a WebService, I got this php error.

explode() expects parameter 2 to be string, null given

$pluginParts = explode('/', pluginSplit($alias)[0]);

Since $alias = 'Posts (my controller), pluginSplit($alias)[0] is null.
And the explode method cannot accept null as the second parameter.

I'm trying to figure out what $connectionName is expecting in this scenario because it could be null if $pluginParts is null.

$connectionName = Inflector::underscore(end($pluginParts));

Can you help me clarify that?
Is that a bug?

Thanks in advanced

Incompatible with DebugKit

What I did
Installed the plugin using composer. Created a new driver App\Lib\SamKnows\Driver\SamKnows.php. Extended it from the AbstractDriver and implemented the method stubs.

Then I added the ConnectionManager::config(Configure::consume('Webservices')); as per the docs over here.

What happened
I got an exception for a missing datasource.
Error: Datasource class Webservices could not be found. Datasource class Webservices could not be found.

⟩ Cake\Datasource\ConnectionRegistry->_throwMissingClassError CORE/src/Core/ObjectRegistry.php, line 87

I believe the problem lays here.
⟩ DebugKit\Panel\SqlLogPanel->initialize ROOT/vendor/cakephp/debug_kit/src/Routing/Filter/DebugBarFilter.php, line 159

What I expected
I expected my application would just be able to render my homepage as normal.

/cc @markstory

Empty custom Endpoint class is required to use non-generic Resource

What i did:

  1. Created /PayPalApi/src/Webservice/PayPalProductsWebservice.php
  2. Created /PayPalApi/src/Model/Endpoint/Schema/PayPalProductSchema.php
  3. Created /PayPalApi/src/Model/Resource/PayPalProduct.php
  4. and test code below:
$expectedClass = \get_class(FactoryLocator::get('Endpoint')->get('PayPalApi.PayPalProducts')->newEmptyEntity())
debug($expectedClass);

What i got:
Muffin\Webservice\Model\Resource

What i expected:
PayPalApi\Model\Resource\PayPalProduct

Work around:
Creating /PayPalApi/src/Model/Endpoint/PayPalProductsEndpoint.php with empty class that extends \Muffin\Webservice\Model\Endpoint changes code result to expected one

PayPalProduct class should be used without requirement of creating empty custom PayPalProductsEndpoint class

Incorrect Namespace

I crated the following driver:

namespace Gutscheinpony\Webservice\Driver;

use Cake\Network\Http\Client;
use Muffin\Webservice\AbstractDriver;

class Gutscheinpony extends AbstractDriver
{
    /**
     * {@inheritDoc}
     */
    public function initialize()
    {
        $this->client(new Client([
            'headers' => [
                'X-Api-Token' => $this->config('token')
            ]
        ]));

        $this->webservice('Offers');
    }
}

As error message I get:

Exception: Webservice class Gutscheinpony/Webservice.Offers (and fallback Gutscheinpony/Webservice.Gutscheinpony) could not be found. in [/var/www/schnaeppchenfuchs/vendor/muffin/webservice/src/AbstractDriver.php, line 218]

If I do it with: (probably it's more correct to specifiy the plugin here)

$this->webservice('Gutscheinpony.Offers');

I get:

Exception: Webservice class Gutscheinpony/Webservice.Gutscheinpony.Offers (and fallback Gutscheinpony/Webservice.Gutscheinpony) could not be found. in [/var/www/schnaeppchenfuchs/vendor/muffin/webservice/src/AbstractDriver.php, line 218]

It seems that the namespace building doesn't work properly here.

I think this https://github.com/UseMuffin/Webservice/blob/master/src/AbstractDriver.php#L95 needs to be -1, then it would work (but only for $this->webservice('Offers');) . I'm not sure here if this should be the error I will create a PR.

Endpoint Default Connection Name 'App'

A driver with a class of 'App\Webservice\Driver\FreshService' ends up trying to load a datasource named 'app' instead of something like Webservice\FreshService pr Driver\FreshService. I've tracked down the issue to Webservice/src/Model/Endpoint.php function defaultConnectionName(): string

I'm new to this framework however the default behavior of looking for Datasource > app didn't seem quite right.

[cake 3.10, webservice 2.10] Wrong query result

Cakephp 3.10
Webservice 2.10

I use webservice package to get remote data like this:

    {
        "id": 37744,
        "name": "A19-R35",
        "latitude": 40.427244444444,
        "timestamp": 1633612408,
        "longitude": 17.477786666667
    },
    {
        "id": 37776,
        "name": "A99-S440T",
        "latitude": 40.427088888889,
        "timestamp": 1633611825,
        "longitude": 17.47781
    },
    {
        "id": 37821,
        "name": "A134-S180",
        "latitude": 41.626684444444,
        "timestamp": 1627731959,
        "longitude": 13.319757777778
    },
    {
        "id": 38066,
        "name": "A139-S440T",
        "latitude": 38.055973333333,
        "timestamp": 1633562464,
        "longitude": 13.113187777778
    },
    {
        "id": 38353,
        "name": "A29-V380",
        "latitude": 40.4250433,
        "timestamp": 1633611852,
        "longitude": 17.4824466
    },
    {
        "id": 38696,
        "name": "A62-S190",
        "latitude": 40.94256,
        "timestamp": 1633601755,
        "longitude": 9.5173666
    },
    {
        "id": 38750,
        "name": "A40-VM90",
        "latitude": 40.7200366,
        "timestamp": 1633411097,
        "longitude": 8.6301933
    },
    {
        "id": 38751,
        "name": "A46-S190",
        "latitude": 40.6871316,
        "timestamp": 1633593958,
        "longitude": 8.62475
    },
    {
        "id": 38760,
        "name": "A96-l75",
        "latitude": 39.8879566,
        "timestamp": 1633593014,
        "longitude": 8.5964433
    },
    {
        "id": 38786,
        "name": "A137-ACM90",
        "latitude": 39.3558099,
        "timestamp": 1633604014,
        "longitude": 9.05761
    },
    {
        "id": 38787,
        "name": "A38-VM90",
        "latitude": 39.9739633,
        "timestamp": 1633429440,
        "longitude": 9.6387783
    },
    {
        "id": 38790,
        "name": "A134-S180",
        "latitude": 39.35592,
        "timestamp": 1633606331,
        "longitude": 9.0577099
    },
    {
        "id": 38791,
        "name": "A49-I90",
        "latitude": 39.3560433,
        "timestamp": 1633602699,
        "longitude": 9.057675
    },
    {
        "id": 38829,
        "name": "A25-R293",
        "latitude": 42.566625,
        "timestamp": 1633611572,
        "longitude": 12.9755516
    }
]

If I do a get:

$this->Vehicles->get(38751);

or a find with conditions:

$this->Vehicles->find()->where(['id' => 38751])->toArray()

return same the first element of list:

{
    "id": 37744,
    "name": "A19-R35",
    "latitude": 40.427244444444,
    "timestamp": 1633612675,
    "longitude": 17.477786666667
}

Unable to transform single item api responses

What I did

Created the Model/Endpoint/IplookupEndpoint.php and Model/Resource/Iplookup.php files. Then loaded my model and hit the endpoint.

    public function iplookup()
    {
        $this->loadModel('Gaia/Supply.Iplookup', 'Endpoint');

        $ipData = $this->Iplookup->find()
            ->where(['ip' => $this->request->query('ip')])
            ->execute();

        $this->set('ipData', $ipData);
    }

What I expected to happen

I would expect a single Iplookup resource back.

What actually happened

I got a TypeError exception.
Argument 2 passed to Muffin\Webservice\Webservice\Webservice::_transformResource() must be of the type array, string given, called in /Users/david/Sites/Gaia/vendor/muffin/webservice/src/Webservice/Webservice.php on line 321

What does my api response look like

{
  "success": true,
  "data": {
    "city": {
      "city": {
        "geoname_id": 5375480,
        "names": {
          "de": "Mountain View",
          "en": "Mountain View",
          "fr": "Mountain View",
          "ja": "マウンテンビュー",
          "ru": "Маунтин-Вью",
          "zh-CN": "芒廷维尤"
        }
      },
      "continent": {
        "code": "NA",
        "geoname_id": 6255149,
        "names": {
          "de": "Nordamerika",
          "en": "North America",
          "es": "Norteamérica",
          "fr": "Amérique du Nord",
          "ja": "北アメリカ",
          "pt-BR": "América do Norte",
          "ru": "Северная Америка",
          "zh-CN": "北美洲"
        }
      },
      "country": {
        "geoname_id": 6252001,
        "iso_code": "US",
        "names": {
          "de": "USA",
          "en": "United States",
          "es": "Estados Unidos",
          "fr": "États-Unis",
          "ja": "アメリカ合衆国",
          "pt-BR": "Estados Unidos",
          "ru": "Сша",
          "zh-CN": "美国"
        }
      },
      "location": {
        "latitude": 37.386,
        "longitude": -122.0838,
        "metro_code": 807,
        "time_zone": "America/Los_Angeles"
      },
      "postal": {
        "code": "94040"
      },
      "registered_country": {
        "geoname_id": 6252001,
        "iso_code": "US",
        "names": {
          "de": "USA",
          "en": "United States",
          "es": "Estados Unidos",
          "fr": "États-Unis",
          "ja": "アメリカ合衆国",
          "pt-BR": "Estados Unidos",
          "ru": "Сша",
          "zh-CN": "美国"
        }
      },
      "subdivisions": [
        {
          "geoname_id": 5332921,
          "iso_code": "CA",
          "names": {
            "de": "Kalifornien",
            "en": "California",
            "es": "California",
            "fr": "Californie",
            "ja": "カリフォルニア州",
            "pt-BR": "Califórnia",
            "ru": "Калифорния",
            "zh-CN": "加利福尼亚州"
          }
        }
      ],
      "traits": {
        "ip_address": "8.8.8.8"
      }
    },
    "isp": "Level 3 Communications",
    "provider": false
  }
}

What I think is happening

I think that the Webservice::_transformResults is assuming that the return is an array of items, and not a single item. As such it's using a foreach loop and making an assumption that each value in the array should also be an array.

Unknown repository type error

I have clear install of CakePHP (latest).

After I've followed all of the steps provided in the "Usage" section of this plugin I'm stuck on the Unknown repository type "Endpoint". Make sure you register a type before trying to use it. error.

Not sure how to register this type. I've tried

public function beforeFilter(Event $event)
{
$this->modelFactory(
'Endpoint',
['Endpoint', 'factory']
);
$this->loadModel('Articles', 'Endpoint');
}

but got Argument 2 passed to Cake\Controller\Controller::modelFactory() must be callable, array given error.

CrudView should be supported

It should be possible to use CrudView with the Webservice plugin. For this quite a few things have to happen.

Some of the things that need to change:

  • FoC/Search should use the general repository interface: \Cake\Datasource\RepositoryInterface FriendsOfCake/search#79
  • \Search\Model\Behavior\SearchBehavior needs to be somehow compatible with \Muffin\Webservice\Model\Endpoint classes. Possibly by using traits. Interesting PR: cakephp/elastic-search#83.
  • Search Filter classes need to be less dependent on query expressions (at least simple cases like \Search\Model\Filter\Value). Currently the only way to use Search is to use the \Search\Model\Filter\Callback filter.
  • CrudView should use the general entity interface: \Cake\Datasource\EntityInterface (for example in the CrudViewHelper)
  • \Muffin\Webservice\Query needs to have the contain method
  • \Muffin\Webservice\Endpoint requires some notion of defining associations.

It might be necessary to change the CakePHP core to add more methods to specific interfaces. Some of the things that need to be made:

  • \Cake\Datasource\AssociationInterface to describe a general association between two RepositoryInterface implementations. cakephp/cakephp#9002.

Create, Update & Delete Examples

I have been successfully able to get a read query working, but unable to get create and update working. I've looked through community examples but I'm unable to find any examples of doing create, update and delete calls from the controller. Does anyone have an example of how they would look? My confusion is arising from normally using patchEntity then save, however, an entity is not applicable.

I'm trying to connect to a Magento 2 REST API
POST /V1/products
PUT /V1/products/:sku
DELETE /V1/products/:sku
GET /V1/products
GET /V1/products/:sku

Method signature causing Fatal Error (cake-4.x)

Hello,

I am new to using your package, and I want to share the following issue on one of your dev branches.
The class Muffin\Webservice\Datasource\Query is causing the following Fatal Error, as the method signature is not compliant with the one in CakePHP's QueryTrait :

Declaration of Muffin\Webservice\Datasource\Query::_execute() must be compatible with Cake\Datasource\QueryTrait::_execute(): Cake\Datasource\ResultSetInterface in /var/www/html/vendor/muffin/webservice/src/Datasource/Query.php on line 549

This error occured on branch cake-4.x, as I am using CakePHP 4.2.

Best regards and thanks for your work on this package !

Cyclical looping

What I did

<?php
// ExampleWebservice
public funcion __construct(array $config = [])
{
    parent::__construct($config);
    $this->driver(new ExampleDriver());
}

// ExampleDriver
public function initialize()
{
    $this->webservice(new ExampleWebservice());
}

// Setup the Endpoint
$endpoint = new ExampleEndpoint([
    'connection' => new ExampleDriver(),
    'endpoint' => 'Example'
]);

What happened?

Fatal error: Maximum function nesting level of '256' reached, aborting! in /Users/david/Sites/gaia-supply/vendor/muffin/webservice/src/Webservice/Webservice.php on line 52

What I expected to happen

I'd just expect the relevant settings to be setup in each class

How to get pagination data?

My api response contains a meta element with the pagination data for the response.

{
    "meta": {
        "pagination": {
            "page": 1,
            "next_page": 2,
            "previous_page": null,
            "total_results": 102,
            "total_pages": 6,
            "per_page": 20
        }
    },
    "body": {
        "results": [
            {
                "id": 530,
                "name": "Unlimited Broadband",
// etc

However when the response is parsed into a Resource this data is lost. I can't see it in Muffin\Webservice\Query which makes sense as it's not been executed yet. However when it is executed it will be converted into a Resource, so it's lost then also.

I would rather know from the preceding request if there is a next page or not rather than intentionally making a 404 request to find the last page.

Missing exception

It seems that this class is missing from the repo.

Muffin\Webservice\Exception\UnimplementedWebserviceMethodException

Marshaller throws a warning

@Marlinc Please correct me if I'm wrong but I think this condition will throw a warning almost everytime, when an empty string will be marshalled: https://github.com/UseMuffin/Webservice/blob/master/src/Marshaller.php#L71

It's probably a copy/paste issue from Cake's ORM but this will return usually a string: https://github.com/UseMuffin/Webservice/blob/master/src/Marshaller.php#L53

On Cake's ORM it will always return an array, why it works there: https://github.com/cakephp/cakephp/blob/master/src/Database/Schema/Table.php#L505

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.