[IDEA] RESTful service client #3635

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

Comments

Projects
None yet
@creocoder
Contributor

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

This comment has been minimized.

Show comment
Hide comment
@qiangxue

qiangxue May 29, 2014

Member

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

Member

qiangxue commented May 29, 2014

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

@creocoder

This comment has been minimized.

Show comment
Hide comment
@creocoder

creocoder May 30, 2014

Contributor

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

Contributor

creocoder commented May 30, 2014

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

@creocoder

This comment has been minimized.

Show comment
Hide comment
@creocoder

creocoder May 30, 2014

Contributor

@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.

Contributor

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

This comment has been minimized.

Show comment
Hide comment
@qiangxue

qiangxue May 30, 2014

Member

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?

Member

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

This comment has been minimized.

Show comment
Hide comment
@creocoder

creocoder May 30, 2014

Contributor

@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".

Contributor

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

This comment has been minimized.

Show comment
Hide comment
@klimov-paul

klimov-paul May 30, 2014

Member

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.

Member

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

This comment has been minimized.

Show comment
Hide comment
@PrplHaz4

PrplHaz4 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

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

This comment has been minimized.

Show comment
Hide comment
@creocoder

creocoder May 30, 2014

Contributor

@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?

Contributor

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

This comment has been minimized.

Show comment
Hide comment
@klimov-paul

klimov-paul May 31, 2014

Member

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.

Member

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

This comment has been minimized.

Show comment
Hide comment
@creocoder

creocoder May 31, 2014

Contributor

@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.

Contributor

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

This comment has been minimized.

Show comment
Hide comment
@klimov-paul

klimov-paul Jun 1, 2014

Member

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.

Member

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

This comment has been minimized.

Show comment
Hide comment
@creocoder

creocoder Jun 2, 2014

Contributor

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.

Contributor

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

This comment has been minimized.

Show comment
Hide comment
@samdark

samdark Jun 3, 2014

Member

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

Member

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

This comment has been minimized.

Show comment
Hide comment
@angelcoding

angelcoding 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

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

@rlmckenney

This comment has been minimized.

Show comment
Hide comment
@rlmckenney

rlmckenney 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.

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

This comment has been minimized.

Show comment
Hide comment
@jonvargas

jonvargas 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?

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

This comment has been minimized.

Show comment
Hide comment

+1

@thiagotalma

This comment has been minimized.

Show comment
Hide comment
@thiagotalma

thiagotalma Jan 16, 2015

Contributor

How is this issue? Some evolution?

Contributor

thiagotalma commented Jan 16, 2015

How is this issue? Some evolution?

@macklay

This comment has been minimized.

Show comment
Hide comment

macklay commented Jan 17, 2015

+1

@mdmunir

This comment has been minimized.

Show comment
Hide comment
@mdmunir

mdmunir Apr 22, 2015

Contributor

👍

Contributor

mdmunir commented Apr 22, 2015

👍

@adipriyantobpn

This comment has been minimized.

Show comment
Hide comment
@adipriyantobpn

adipriyantobpn Apr 30, 2015

+1

any update about this topic? :)

+1

any update about this topic? :)

@kbentlage

This comment has been minimized.

Show comment
Hide comment
@kbentlage

kbentlage 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.

+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

This comment has been minimized.

Show comment
Hide comment
@quarkmarino

quarkmarino 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

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

This comment has been minimized.

Show comment
Hide comment
@cebe

cebe May 8, 2015

Member

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

Member

cebe commented May 8, 2015

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

@quarkmarino

This comment has been minimized.

Show comment
Hide comment
@quarkmarino

quarkmarino 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.

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

This comment has been minimized.

Show comment
Hide comment
@idMolotov

idMolotov 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.

+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

This comment has been minimized.

Show comment
Hide comment
@lexotrion

lexotrion May 27, 2015

+1 We need it!!!

+1 We need it!!!

@nigelterry

This comment has been minimized.

Show comment
Hide comment

+1

@geega

This comment has been minimized.

Show comment
Hide comment

geega commented Jun 3, 2015

+100

@adiramardiani

This comment has been minimized.

Show comment
Hide comment

Same with @quarkmarino vote for Guzzle

@dizews

This comment has been minimized.

Show comment
Hide comment
@dizews

dizews Jun 8, 2015

Contributor

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

Contributor

dizews commented Jun 8, 2015

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

@CheckeredFlag

This comment has been minimized.

Show comment
Hide comment
@CheckeredFlag

CheckeredFlag Jul 27, 2015

Contributor

+1

Contributor

CheckeredFlag commented Jul 27, 2015

+1

@tiagofarinhanunes

This comment has been minimized.

Show comment
Hide comment
@iCloud

This comment has been minimized.

Show comment
Hide comment

iCloud commented Dec 17, 2015

+1

@lav45

This comment has been minimized.

Show comment
Hide comment
@lav45

lav45 Dec 17, 2015

Contributor

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

Contributor

lav45 commented Dec 17, 2015

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

@samdark

This comment has been minimized.

Show comment
Hide comment
@lav45

This comment has been minimized.

Show comment
Hide comment
@lav45

lav45 Dec 17, 2015

Contributor

@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

Contributor

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

This comment has been minimized.

Show comment
Hide comment
@bscheshirwork

bscheshirwork Jan 14, 2016

Contributor

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

Contributor

bscheshirwork commented Jan 14, 2016

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

@Olegf13

This comment has been minimized.

Show comment
Hide comment

Olegf13 commented Mar 3, 2016

+1

@ApexWire

This comment has been minimized.

Show comment
Hide comment

ApexWire commented Mar 3, 2016

+1

@jcleeland

This comment has been minimized.

Show comment
Hide comment

+1

@samdark

This comment has been minimized.

Show comment
Hide comment
Member

samdark commented Apr 15, 2016

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

@ApexWire

This comment has been minimized.

Show comment
Hide comment
@ApexWire

ApexWire 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;

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;
@nderitu

This comment has been minimized.

Show comment
Hide comment
@samdark

This comment has been minimized.

Show comment
Hide comment
@samdark

samdark Aug 17, 2017

Member

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

Member

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