Code Monkey home page Code Monkey logo

Comments (7)

matthttam avatar matthttam commented on May 18, 2024 2

So the application api I am pulling from is called "Freshservice". Thanks for the help on understanding the need for a FreshserviceWebservice that is then extended by things like the TicketsWebservice. However, this didn't correct the issue.

The plugin is still trying to find a datasource called 'app'

Just to be clear, I am using the 3.0.0 beta of your plugin as I am in CakePHP 4. So I replicated the example GitHub webservice and updated all of the functions and namespaces. Still, the app is trying to find a datasource called 'app' instead of 'Freshservice'.

Here is my setup:
Freshservice Driver located in src\Webservice\Driver\Freshservice.php:
`namespace App\Webservice\Driver;

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

class Freshservice extends AbstractDriver
{...`

Freshservice Webservice located in src\Webservice\FreshserviceWebservice.php:
`namespace App\Webservice;

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

class FreshserviceWebservice extends Webservice
{`

Tickets Webservice located in src\Webservice\TicketsWebservice.php
`namespace App\Webservice;

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

class TicketsWebservice extends FreshserviceWebservice
{
public function initialize(): void
{
parent::initialize();
}`

Tickets Endpoint located in src\Model\Endpoint\TicketsEndpoint.php
`namespace App\Model\Endpoint;

use Muffin\Webservice\Model\Endpoint;

class TicketsEndpoint extends Endpoint
{`

So, with these files in place, shouldn't it be looking for a datasource called 'freshservice'? Instead I'm getting the error: 'The datasource configuration app was not found in config/app.php.'

from webservice.

matthttam avatar matthttam commented on May 18, 2024

2020-02-22 18:17:41 Error: [Cake\Datasource\Exception\MissingDatasourceConfigException] The datasource configuration "app" was not found. in /home/bil/projects/freshserviceinventory/vendor/cakephp/cakephp/src/Datasource/ConnectionManager.php on line 203
Exception Attributes: array (
'name' => 'app',
)
Stack Trace:

  • /home/bil/projects/freshserviceinventory/vendor/muffin/webservice/src/Model/EndpointLocator.php:101
  • /home/bil/projects/freshserviceinventory/vendor/cakephp/cakephp/src/Datasource/ModelAwareTrait.php:128
  • /home/bil/projects/freshserviceinventory/src/Controller/TicketsController.php:24
  • /home/bil/projects/freshserviceinventory/vendor/cakephp/cakephp/src/Controller/Controller.php:524
  • /home/bil/projects/freshserviceinventory/vendor/cakephp/cakephp/src/Controller/ControllerFactory.php:79
  • /home/bil/projects/freshserviceinventory/vendor/cakephp/cakephp/src/Http/BaseApplication.php:229
  • /home/bil/projects/freshserviceinventory/vendor/cakephp/cakephp/src/Http/Runner.php:77
  • /home/bil/projects/freshserviceinventory/vendor/cakephp/authorization/src/Middleware/RequestAuthorizationMiddleware.php:102
  • /home/bil/projects/freshserviceinventory/vendor/cakephp/cakephp/src/Http/Runner.php:73
  • /home/bil/projects/freshserviceinventory/vendor/cakephp/authorization/src/Middleware/AuthorizationMiddleware.php:129
  • /home/bil/projects/freshserviceinventory/vendor/cakephp/cakephp/src/Http/Runner.php:73
  • /home/bil/projects/freshserviceinventory/vendor/cakephp/authentication/src/Middleware/AuthenticationMiddleware.php:124
  • /home/bil/projects/freshserviceinventory/vendor/cakephp/cakephp/src/Http/Runner.php:73
  • /home/bil/projects/freshserviceinventory/vendor/cakedc/users/src/Middleware/SocialEmailMiddleware.php:34
  • /home/bil/projects/freshserviceinventory/vendor/cakephp/cakephp/src/Http/Runner.php:73
  • /home/bil/projects/freshserviceinventory/vendor/cakedc/users/src/Middleware/SocialAuthMiddleware.php:124
  • /home/bil/projects/freshserviceinventory/vendor/cakephp/cakephp/src/Http/Runner.php:73
  • /home/bil/projects/freshserviceinventory/vendor/cakephp/cakephp/src/Http/Runner.php:77
  • /home/bil/projects/freshserviceinventory/vendor/cakephp/cakephp/src/Http/Middleware/CsrfProtectionMiddleware.php:132
  • /home/bil/projects/freshserviceinventory/vendor/cakephp/cakephp/src/Http/Runner.php:73
  • /home/bil/projects/freshserviceinventory/vendor/cakephp/cakephp/src/Http/Runner.php:58
  • /home/bil/projects/freshserviceinventory/vendor/cakephp/cakephp/src/Routing/Middleware/RoutingMiddleware.php:162
  • /home/bil/projects/freshserviceinventory/vendor/cakephp/cakephp/src/Http/Runner.php:73
  • /home/bil/projects/freshserviceinventory/vendor/cakephp/cakephp/src/Routing/Middleware/AssetMiddleware.php:68
  • /home/bil/projects/freshserviceinventory/vendor/cakephp/cakephp/src/Http/Runner.php:73
  • /home/bil/projects/freshserviceinventory/vendor/cakephp/cakephp/src/Error/Middleware/ErrorHandlerMiddleware.php:118
  • /home/bil/projects/freshserviceinventory/vendor/cakephp/cakephp/src/Http/Runner.php:73
  • /home/bil/projects/freshserviceinventory/vendor/cakephp/debug_kit/src/Middleware/DebugKitMiddleware.php:60
  • /home/bil/projects/freshserviceinventory/vendor/cakephp/cakephp/src/Http/Runner.php:73
  • /home/bil/projects/freshserviceinventory/vendor/cakephp/cakephp/src/Http/Runner.php:58
  • /home/bil/projects/freshserviceinventory/vendor/cakephp/cakephp/src/Http/Server.php:90
  • /home/bil/projects/freshserviceinventory/webroot/index.php:40

Request URL: /Tickets
Client IP: 127.0.0.1

So my implementation is very basic at the moment.

I've got a TicketsController with an index function that only does this:
$this->loadModel('Tickets', 'Endpoint');

I've created a src/Webservice/Driver/Freshservice.php driver which extends AbstractDriver and calls setClient in its initialize function.

I've created a Model/Endpoint/TicketsEndpoint that extends Endpoint and has nothing else in it.
I've created a src/Webservice/TicketsWebservice that extends Muffin\Webservice\Webservice\Webservice . This has a function _executeReadQuery like so:

`protected function _executeReadQuery(Query $query, array $options = [])
{

    $response = $this->getDriver()->getClient()->get('/tickets',[],[ 'auth' => ['username' => '', 'password' => 'X']]);
    //debug('here');
    if (!$response->isOk()) {
        return false;
    }
    //debug($response->getJson());
    $resources = $this->_transformResults($query->getEndpoint(), $response->getJson()['tickets']);
    //debug($resources);
    //return '';
    return new ResultSet($resources, count($resources));
}`

So for some reason my setup is trying to look in config/app.php for datasource -> app. If I add this to my datasources:
'app' => [ 'className' => 'Muffin\Webservice\Datasource\Connection', 'service' => 'App\Webservice\Driver\Freshservice', 'host' => 'mysite.freshservice.com/api/v2/', //'api_key' => '', ],
It actually works. But I really don't want "app" to be the name of the datasource and I don't see a way to change the configuration.

debug_kit shows that Muffin\Webservice\Model\EndpointLocator->get is being passed:
'Tickets' [ 'alias' => 'Tickets', 'className' => 'App\Model\Endpoint\TicketsEndpoint' ]

Cake\Datasource\ConnectionManager::get is being passed 'app'

As I mentioned earlier, I tracked down this 'app' argument to the defaultConnectionName(): string which is taking my class name 'App\Model\Endpoint\TicketsEndpoint', splitting by '\', reversing it, then array_split with 3, 2... which is just getting the word 'app'.

` public static function defaultConnectionName(): string
{
$namespaceParts = explode('\', static::class);
$plugin = array_slice(array_reverse($namespaceParts), 3, 2);

    return Inflector::underscore(current($plugin));
}`

I'm probably just doing something wrong or I need to add some sort of config somewhere but I can't figure out how to fix it.

from webservice.

ADmad avatar ADmad commented on May 18, 2024

Have you made App\WebService\FreshWebservice class? Also your driver class should be App\WebService\Driver\Fresh, proper casing and naming convention matters. Then you need datasource config named fresh in your app config.

Refer to the Github webservice for example https://github.com/cvo-technologies/cakephp-github

from webservice.

matthttam avatar matthttam commented on May 18, 2024

I thought I'd take another look and try to figure this out.
cake-4.x branch file: src/Model/Endpoint.php
Method defaultConnectionName() which is used when loaded with the EndpointLocator I think.

public static function defaultConnectionName(): string
    {
        $namespaceParts = explode('\\', static::class);
        $plugin = array_slice(array_reverse($namespaceParts), 3, 2);

        return Inflector::underscore(current($plugin));
    }

One endpoint I am using has the following static::class "App\Model\Endpoint\AssetsEndpoint"
The function above sets namespace parts by exploding that class name as such:
$namespaceParts = Array ( [0] => App [1] => Model [2] => Endpoint [3] => AssetsEndpoint )
Then we do array_reverse($namespaceParts); Which returns:
Array ( [0] => AssetsEndpoint [1] => Endpoint [2] => Model [3] => App )
This is passed into array_slice(thearray, 3, 2)
This returns Array ( [0] => App )

So, this function makes sense if I were to create a plugin... but I'm using it directly in my project to perform API calls. Is that not intended?

from webservice.

matthttam avatar matthttam commented on May 18, 2024

So I spent today learning how to put together a plugin... getting that working... then learning how to split it into its own repository... then submitting it to packagelist. I now have a working freshservice API plugin requiring your plugin. It is now looking for the proper config name 'freshservice' instead of 'app'.

https://bitbucket.org/matt_henry_ops/freshservice

It is still very much a work in progress but this is working so far! Sorry for any confusion on my part. I thought I could just use the webservice plugin directly in my regular application... If I should be able to do this then the above code should either account for this or documentation on how to set the proper config name would be good.

Thanks!

from webservice.

ADmad avatar ADmad commented on May 18, 2024

Thanks for providing the detailed analysis and congrats on learning all the new stuff related to plugin development and publishing, that will definitely help you in future 🙂.

So when loading an endpoint class we don't have any info about which webservice it's related to and what connection it should use. Hence we have to resort to guess work based on the FQCN to get the connection name.

We could try to improve the connection name guessing or just clarify that users should override the Endpoint::defaultConnectionName() and make it return the connection to use. Since we don't really have much documentation the endpoint class under Create an endpoint (optional) section in readme could include the defaultConnectionName() method.

Given all the various classes needed for a webservice I would recommend organizing them using a plugin regardless. One can make an "app plugin" and doesn't necessarily need to publish it to packagist.

from webservice.

ADmad avatar ADmad commented on May 18, 2024

Closed by #88

from webservice.

Related Issues (20)

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.