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

[IDEA] RESTful service client #3635

Closed
creocoder opened this issue May 29, 2014 · 46 comments
Closed

[IDEA] RESTful service client #3635

creocoder opened this issue May 29, 2014 · 46 comments

Comments

@creocoder
Copy link
Contributor

@creocoder creocoder commented May 29, 2014

How i see that. Several classes:

\yii\rest\Resource extends \yii\base\Model
\yii\rest\Client
\yii\rest\DataProvider

and probably:

\yii\rest\Request

Configuring:

    'components' => [
        'rest' => [
            'class' => 'yii\rest\Client',
            'url' => 'https://api.example.com',
        ],
    ],

Example of resource class:

class Post extends \yii\rest\Resource
{
    public static resourceName()
    {
        return 'posts';
    }

    public function attributes()
    {
        return ['id', 'title', 'body'];
    }

    public function rules()
    {
        // return rules for attributes
    }
}

Now we can do:

$posts = Post::getAll();
$posts = Post::getAll(['author' => 'creocoder']);

$post = Post::getOne(10);
$post = Post::getOne(10, ['is_published' => true]);

$post = new Post;
$post->title = 'New title';
$post->body = 'Body';
$post->post();

$post = Post::getOne(10);
$post->title = 'Updated title';
$post->put();

For data provider there is 2 alternative ideas:

$dataProvider = new \yii\rest\DataProvider(
    'resource' => new Post,
);

and

$request = Post::find(); // \yii\rest\Request class

$dataProvider = new \yii\rest\DataProvider(
    'request' => $request,
);

Why custom DataProvider? To work with current \yii\rest\ActiveController and other components and play well with headers which containts pagination data, total count, etc.

@qiangxue What you think about it?

@qiangxue
Copy link
Member

@qiangxue qiangxue commented May 29, 2014

What's new of your proposal compared with the current REST implementation?

@creocoder
Copy link
Contributor Author

@creocoder creocoder commented May 30, 2014

@qiangxue Your implementation is service. This is client. It absolutte different.

@creocoder
Copy link
Contributor Author

@creocoder creocoder commented May 30, 2014

@qiangxue Currently we can create RESTful service with Yii 2 and \yii\rest components. This additional set of components will help to create REST clients with Yii 2.

@qiangxue
Copy link
Member

@qiangxue qiangxue commented May 30, 2014

I see. Perhaps it should use a different namespace to avoid confusion? Also, there are many different REST API implementations. How would you design these classes to accommodate the differences? For example, the pagination information may be sent in different ways. How will DataProvider know where to look for this information?

@creocoder
Copy link
Contributor Author

@creocoder creocoder commented May 30, 2014

@qiangxue This is why i post is as just idea to start discussion around it. DataProvider can take into account our service implementation, at least. We can make it customizable as possible. Why this idea born? Currently Yii 2 offer RESTful service and nothing around client implementations. I just try to improve situation. Currently i'm not sure about approach we need to use. But this issue is good start point to think about "Implementing REST clients with Yii 2".

@klimov-paul
Copy link
Member

@klimov-paul klimov-paul commented May 30, 2014

If I whould create an extension to provide some 'fancy' program interface for REST service, I would create an 'Query/ActiveRecord/ActiveQuery' type extension. Like the one for 'ElasticSearch'.
'ElasticSearch' is a storage, which have REST protocol interface, allowing you add, updated and select data, including pagination and so on.

Still I am unsure such extension is worth the effots. I have worked with many APIs including ones using REST. But I can not remember any of them following REST standards at full scope.
Implementing particular service client will require too many significant changes in such extension.

@PrplHaz4
Copy link

@PrplHaz4 PrplHaz4 commented May 30, 2014

I believe similar functionality is implemented in the ActiveResource extension for Yii1 - maybe @Haensel has some learnings he could share...

https://github.com/Haensel/ActiveResource

@creocoder
Copy link
Contributor Author

@creocoder creocoder commented May 30, 2014

@klimov-paul I do not think Query/ActiveQuery needed here. REST does not need its features, only where and only hash format for it. This is why all those features can be handled with $params inside getAll() or findAll() if create similar to AR API.

I have worked with many APIs including ones using REST. But I can not remember any of them following REST standards at full scope.

Example?

@klimov-paul
Copy link
Member

@klimov-paul klimov-paul commented May 31, 2014

I do not think Query/ActiveQuery needed here. REST does not need its features, only where and only hash format for it.

Well, we can also say there is no need for specific extension for REST client as it not so complicated. Creating full scale Active Record layer will make such extension consitent with other framework parts. Creating a model for the rest data set allows working with via regular Yii forms. Also framework allows cross AR relations, which means we can link REST resource to relational database, which may be useful.
In such Query is useful in terms of ordering and pagination (limit+offset handling). If such functionality can be placed there, we can use regular ActiveDataProvider with it.

@creocoder
Copy link
Contributor Author

@creocoder creocoder commented May 31, 2014

@klimov-paul

Well, we can also say there is no need for specific extension for REST client as it not so complicated.

Really??? Can you show Yii 2 application "Client of RESTful service"??? Not complicated without such layer? Ok, i'm ready to belive with simple example ;-) For now such task (without such components) looks like super complicated.

Creating full scale Active Record layer will make such extension consitent with other framework parts.

It theory yes. But trying to implement it show that Yii 2 ActiveRecord/ActiveQuery/Query interfaces absolutte not ready for working with RESTful services with components based on it.

If such functionality can be placed there, we can use regular ActiveDataProvider with it.

At first look yes. I'm also think so 3 days ago. Can NOT be used at all. To understand why think about header "X-Page-Total-Count" and about headers... What ActiveDataProvider know about headers? Nothing!

Query

Great. Think what you will send to RESTful service when using offset() and limit() methods :-)

There is many reasons why you can't look at RESTful services like on SQL/Non-SQL DBs. This need other approach. Yes its API can look like ActiveRecord/ActiveQuery classes API, but can't implement current interfaces or extends current classes.

@klimov-paul
Copy link
Member

@klimov-paul klimov-paul commented Jun 1, 2014

For now such task (without such components) looks like super complicated.

My first expirience with REST wa 5 years ago, when Yii did not even exist. I have used pure curl commands to work with REST and I can not tell that was something extremely complicated.
Nowdays, if you do not want to run deep into curl, you can always use Guzzle.
Of course REST client if not something to be made at once, but I can not see anything, which qualified developer can not handle in it.
Still if anyone is ready to compose an extension for it in some way - I whould be greatful.

There is many reasons why you can't look at RESTful services like on SQL/Non-SQL DBs

What about ElasticSearch then? Its interface follows REST standard, @cebe have composed a fine solution for it with Active Record layer:
https://github.com/yiisoft/yii2/tree/master/extensions/elasticsearch
For me this extension is a livng example approach, which I propose is acceptable,

To understand why think about header "X-Page-Total-Count" and about headers... What ActiveDataProvider know about headers? Nothing!

Yes, and it should. That is why Query class is useful - it can incapsulate pagination logic, processing headers and so on.

@creocoder
Copy link
Contributor Author

@creocoder creocoder commented Jun 2, 2014

Of course REST client if not something to be made at once, but I can not see anything, which qualified developer can not handle in it.

I agree that qualified developer can even develop web app with pure php. But how does qualification related to set of components which just comfortable to use? Seems even qualified developer use frameworks, etc ;-)

What about ElasticSearch then? Its interface follows REST standard, @cebe have composed a fine solution for it with Active Record layer

I learned @cebe extension before i say you that basing ActiveResource components on existing Yii 2 components/interfaces is impossible. At least without refactoring its architecture. Ok I'll show you simple example from ActiveDataProvider:

    protected function prepareTotalCount()
    {
        ...
        $query = clone $this->query;
        return (int) $query->limit(-1)->offset(-1)->orderBy([])->count('*', $this->db);
    }

You see that? What that mean? There will be 2nd query to REST server in addition to main query. But we need one query to get all data we need. And there is A LOT of such nuances. I can list some of them:

  • Query::limit() in context of REST service
  • Query::offset() in context of REST service
  • Query::count do we really need 2nd query? its not optimal
  • another 100th reasons why creating ActiveResource on base of existing components is very bad idea.

For me personally i found another way. Its creating Service classes like:

https://github.com/zendframework/ZendService_Twitter

And using Zend/Http/Client instead of Guzzle.

@samdark samdark added this to the 2.1 milestone Jun 3, 2014
@samdark
Copy link
Member

@samdark samdark commented Jun 3, 2014

Set milestone to 2.1 for now (it doesn't mean it can't go into 2.0 if there's a pull request).

@angelcoding
Copy link

@angelcoding angelcoding commented Jun 12, 2014

Not used it myself (yet) but perhaps Trucker can be used for this or at least provide inspiration - https://github.com/Indatus/trucker

@rlmckenney
Copy link

@rlmckenney rlmckenney commented Aug 23, 2014

I think this would be a very useful addition to the framework. More and more of my projects involve grafting in some external functionality or data source via RESTful API. In looking at how to implement this, consider the Httpful curl wrapper from Nate Good https://github.com/nategood/httpful - it can be a example for some of the core functions in implementing a generic REST API accessor.

@jonvargas
Copy link

@jonvargas jonvargas commented Oct 17, 2014

This looks great, we started developing an application on Yii, that doesn't use a database at all, and all CRUD operations go through a RESTful API. So, we are wondering now how to design the solution to get a similar functionality provided by ActiveRecord, so that it could be compatible with all Yii forms, widgets, data binding and validations.

No more news, ideas, approaches about this?

@branimir93
Copy link

@branimir93 branimir93 commented Jan 11, 2015

+1

@thiagotalma
Copy link
Contributor

@thiagotalma thiagotalma commented Jan 16, 2015

How is this issue? Some evolution?

@macklay
Copy link

@macklay macklay commented Jan 17, 2015

+1

1 similar comment
@mdmunir
Copy link
Contributor

@mdmunir mdmunir commented Apr 22, 2015

👍

@adipriyantobpn
Copy link

@adipriyantobpn adipriyantobpn commented Apr 30, 2015

+1

any update about this topic? :)

@kbentlage
Copy link

@kbentlage kbentlage commented May 8, 2015

+1

I am working a lot with multiple Yii2 applications which communicating over REST with each other. Such REST client should be very helpful here.

@quarkmarino
Copy link

@quarkmarino quarkmarino commented May 8, 2015

Actually i've been tinkering with Guzzle (http://guzzle.readthedocs.org/en/latest/) library and is pretty neat, with all the service descriptions and event system, it really works great, it could be wrapped to add to yii, I though

@cebe
Copy link
Member

@cebe cebe commented May 8, 2015

what would be the benefit of a wrapper? Why not use it directly?

@quarkmarino
Copy link

@quarkmarino quarkmarino commented May 8, 2015

Yes, of curse it could be used directly, but I guess it could be better structured to where to put the different things it uses, I mean, for me it was a little of a pain, to give it the propper structure and still is, the clients, descriptions, subscribers, responses, some parsers to implement in some cases, etc, at first glance, you get overwhelmed. Just an idea.

@idMolotov
Copy link

@idMolotov idMolotov commented May 15, 2015

+1

need to connect restful users with accounts in new system developed on Yii2.
System set different access level for users but still need some CRUD functionality for REST data.

@lexotrion
Copy link

@lexotrion lexotrion commented May 27, 2015

+1 We need it!!!

@nigelterry
Copy link

@nigelterry nigelterry commented Jun 3, 2015

+1

@geega
Copy link

@geega geega commented Jun 3, 2015

+100

@adiramardiani
Copy link

@adiramardiani adiramardiani commented Jun 8, 2015

Same with @quarkmarino vote for Guzzle

@dizews
Copy link
Contributor

@dizews dizews commented Jun 8, 2015

I think it should be an ActiveResource class with interface like in ActiveRecord.

@CheckeredFlag
Copy link
Contributor

@CheckeredFlag CheckeredFlag commented Jul 27, 2015

+1

1 similar comment
@tiagofarinhanunes
Copy link

@tiagofarinhanunes tiagofarinhanunes commented Jul 31, 2015

+1

@iCloud
Copy link

@iCloud iCloud commented Dec 17, 2015

+1

@lav45
Copy link
Contributor

@lav45 lav45 commented Dec 17, 2015

See "Tools to use API as ActiveRecord for Yii2" => https://github.com/hiqdev/yii2-hiar

@samdark
Copy link
Member

@samdark samdark commented Dec 17, 2015

@lav45
Copy link
Contributor

@lav45 lav45 commented Dec 17, 2015

@samdark , He's the most )
Immediately necessary to provide HTTP caching 304 not modified
It would be nice if the client supplied with the server part

@bscheshirwork
Copy link
Contributor

@bscheshirwork bscheshirwork commented Jan 14, 2016

"hiqdev/yii2-hiart" v 0.0.2 (dev) use Guzzle

@Olegf13
Copy link

@Olegf13 Olegf13 commented Mar 3, 2016

+1

2 similar comments
@ApexWire
Copy link

@ApexWire ApexWire commented Mar 3, 2016

+1

@jcleeland
Copy link

@jcleeland jcleeland commented Apr 5, 2016

+1

@samdark
Copy link
Member

@samdark samdark commented Apr 15, 2016

@ApexWire what's the difference from https://github.com/hiqdev/yii2-hiart?

@ApexWire
Copy link

@ApexWire ApexWire commented Apr 18, 2016

Default Yii2 Rest creates APIs, which is presented here:
https://github.com/yiisoft/yii2/blob/master/docs/guide/rest-quick-start.md#trying-it-out-

In https://github.com/hiqdev/yii2-hiart other APIs, which are not compatible Yii2 Rest and require design improvements. For example:

GET /users: list all users page by page;
POST /users/Create: create a new user;
GET /users/GetInfo?id=123: return the details of the user 123;
PATCH /users/Update?id=123 and PUT /users/Update?id=123: update the user 123;
DELETE /users/Delete?id=123: delete the user 123;
@samdark
Copy link
Member

@samdark samdark commented Aug 17, 2017

I think it's time to close this issue. There are well implemented clients and clients overall aren't as common in server apps.

@samdark samdark closed this Aug 17, 2017
@cebe cebe removed this from the 2.1.x milestone Aug 17, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
You can’t perform that action at this time.