Provide web-api support #303

Closed
Ragazzo opened this Issue May 17, 2013 · 233 comments

Comments

@Ragazzo
Contributor

Ragazzo commented May 17, 2013

I think it can be useful if Yii will provide some web-api support, for example REST, with catching event when request starts, also if Yii will provide some CRestAction < CAction, maybe other workaround can be here to fit REST, what do u think? Situation is common enough so if Yii will give developers some basis it can be good.

Features to implement

  • API Testing Framework (RC)
  • File upload support (RC) moved to #4477
  • Batch queries with transactions support and error handling. (GA or post GA) moved to #4478
  • Searching and filtering (GA or post GA) moved to #4479
  • Automatic API Documentation Generation (e.g. via https://developers.helloreverb.com/swagger/) (GA or post GA) moved to #2684
  • Ability to serve in multiple formats: JSON, JSONP, XML.
  • Pagination for collections.
  • Documentation about which HTTP codes to return when.
  • Documentation on how to implement authentication.
@samdark

This comment has been minimized.

Show comment
Hide comment
@samdark

samdark May 17, 2013

Member

I'm for implementing a base layer for rest APIs. Do you have any good ideas about requirements?

Member

samdark commented May 17, 2013

I'm for implementing a base layer for rest APIs. Do you have any good ideas about requirements?

@Ragazzo

This comment has been minimized.

Show comment
Hide comment
@Ragazzo

Ragazzo May 17, 2013

Contributor

yes, will post them later today here, with maybe some links to resources that also can be useful.

Contributor

Ragazzo commented May 17, 2013

yes, will post them later today here, with maybe some links to resources that also can be useful.

@bwoester

This comment has been minimized.

Show comment
Hide comment
@bwoester

bwoester May 17, 2013

Contributor

More support for RESTful apps would be definitely a good idea. But if something like this is implemented, imo it should be a really solid foundation.

I certainly don't wanna start to flame here, but just to give a negative example: SOAP-support in 1.x. The idea was really cool, and providing a SOAP service basically by simply annotating your methods could have been a killer feature. But the lack of interoperability with other technologies like java or .net really limited its usability. Also, it didn't provide some enhanced features like the ws-* extensions (never checked if they could have been implemented as extensions though, which would have been okay).

For support of RESTful apps, I think some of the most important requirements would be:

  • authentication - pops up in the forum again and again. Can't be provided out of the box, but definitely should be documented in more detail
  • paged collections - unpaged just won't scale
  • for sub-collections, there should be a ways to switch between including them directly and referencing them
  • include/ exclude resource attributes by default, with the possibility for the client to override these defaults
  • service discoverability
  • possibility to use custom output renderers - while I think json would be a good default, xml remains an alternative
  • obviously, it should be easy to re-use your existing models as REST resources

I liked the REST with spring series, it explains a lot of the concepts around REST, so it's worth reading even if you don't use spring.

Contributor

bwoester commented May 17, 2013

More support for RESTful apps would be definitely a good idea. But if something like this is implemented, imo it should be a really solid foundation.

I certainly don't wanna start to flame here, but just to give a negative example: SOAP-support in 1.x. The idea was really cool, and providing a SOAP service basically by simply annotating your methods could have been a killer feature. But the lack of interoperability with other technologies like java or .net really limited its usability. Also, it didn't provide some enhanced features like the ws-* extensions (never checked if they could have been implemented as extensions though, which would have been okay).

For support of RESTful apps, I think some of the most important requirements would be:

  • authentication - pops up in the forum again and again. Can't be provided out of the box, but definitely should be documented in more detail
  • paged collections - unpaged just won't scale
  • for sub-collections, there should be a ways to switch between including them directly and referencing them
  • include/ exclude resource attributes by default, with the possibility for the client to override these defaults
  • service discoverability
  • possibility to use custom output renderers - while I think json would be a good default, xml remains an alternative
  • obviously, it should be easy to re-use your existing models as REST resources

I liked the REST with spring series, it explains a lot of the concepts around REST, so it's worth reading even if you don't use spring.

@samdark

This comment has been minimized.

Show comment
Hide comment
@samdark

samdark May 17, 2013

Member

I'm for never including sub-collection data directly. A reference in a good API should be URL.

Can you elaborate about the following?

  1. include/ exclude resource attributes by default, with the possibility for the client to override these defaults
  2. service discoverability
Member

samdark commented May 17, 2013

I'm for never including sub-collection data directly. A reference in a good API should be URL.

Can you elaborate about the following?

  1. include/ exclude resource attributes by default, with the possibility for the client to override these defaults
  2. service discoverability

@ghost ghost assigned samdark May 17, 2013

@Ragazzo

This comment has been minimized.

Show comment
Hide comment
@Ragazzo

Ragazzo May 17, 2013

Contributor

@samdark i think we need to create new topic on forum and discuss all there to avoid big comments here, what do u think? can u than create topic and link it here in comments?

Contributor

Ragazzo commented May 17, 2013

@samdark i think we need to create new topic on forum and discuss all there to avoid big comments here, what do u think? can u than create topic and link it here in comments?

@Ragazzo

This comment has been minimized.

Show comment
Hide comment
@Ragazzo

Ragazzo May 17, 2013

Contributor

also this book covers some common features to implement with comparison of other API implementation, worth to read this https://blog.apigee.com/detail/is_your_api_naked_10_api_roadmap_considerations_part_1_visibility

Contributor

Ragazzo commented May 17, 2013

also this book covers some common features to implement with comparison of other API implementation, worth to read this https://blog.apigee.com/detail/is_your_api_naked_10_api_roadmap_considerations_part_1_visibility

@bwoester

This comment has been minimized.

Show comment
Hide comment
@bwoester

bwoester May 17, 2013

Contributor

Agree, references should be (absolute) URLs.

But simply never including sub-collections won't be the right solution imo. It might be a default, but there are enough use cases where the data you get is really useful and saves you from doing a lot of additional requests. As an example, think about a gallery that has a collection of categories, each category has a collection of images. If you include the sub-collection of images (maybe with a small page size like 5), you have enough data at hand to display some fancy category preview. And it saves you from introducing a special preview-image attribute in your category (which is purely presentation related and thus shouldn't be part of the resource).

I'll wait for the suggested thread for elaborating on the other stuff. Or if you prefer having it all in one place, I'll comment here later.

Contributor

bwoester commented May 17, 2013

Agree, references should be (absolute) URLs.

But simply never including sub-collections won't be the right solution imo. It might be a default, but there are enough use cases where the data you get is really useful and saves you from doing a lot of additional requests. As an example, think about a gallery that has a collection of categories, each category has a collection of images. If you include the sub-collection of images (maybe with a small page size like 5), you have enough data at hand to display some fancy category preview. And it saves you from introducing a special preview-image attribute in your category (which is purely presentation related and thus shouldn't be part of the resource).

I'll wait for the suggested thread for elaborating on the other stuff. Or if you prefer having it all in one place, I'll comment here later.

@samdark

This comment has been minimized.

Show comment
Hide comment
@samdark

samdark May 17, 2013

Member

@bwoester batch queries will solve it.

Member

samdark commented May 17, 2013

@bwoester batch queries will solve it.

@samdark

This comment has been minimized.

Show comment
Hide comment
@samdark

samdark May 17, 2013

Member

@Ragazzo thanks for the book, will read it.

Member

samdark commented May 17, 2013

@Ragazzo thanks for the book, will read it.

@bwoester

This comment has been minimized.

Show comment
Hide comment
@bwoester

bwoester May 17, 2013

Contributor

@samdark you mean like "get image-collections for categories 1-N"?

Contributor

bwoester commented May 17, 2013

@samdark you mean like "get image-collections for categories 1-N"?

@bwoester

This comment has been minimized.

Show comment
Hide comment
@bwoester

bwoester May 17, 2013

Contributor

About "include/ exclude resource attributes by default, with the possibility for the client to override these defaults": "Web API design" refers to it as "partial response" (p. 16). At least, this is the "possibility for the client to override" portion of what I meant.

Contributor

bwoester commented May 17, 2013

About "include/ exclude resource attributes by default, with the possibility for the client to override these defaults": "Web API design" refers to it as "partial response" (p. 16). At least, this is the "possibility for the client to override" portion of what I meant.

@cebe

This comment has been minimized.

Show comment
Hide comment
@cebe

cebe May 18, 2013

Member

I implemented REST actions some time ago for a project with yii 1.1. They implement the basic CRUD actions and can handle normal CRUD via HTML but also REST requests by returning differen formats like JSON, csv or ical(used for date objects in this project).

Here is a gist with the actions:
https://gist.github.com/cebe/5604091

And this is how a controller uses them:
https://gist.github.com/cebe/5604091#file-myrestcontroller-php

Hope this is good for inspiration and helps finding a good solution :)

Member

cebe commented May 18, 2013

I implemented REST actions some time ago for a project with yii 1.1. They implement the basic CRUD actions and can handle normal CRUD via HTML but also REST requests by returning differen formats like JSON, csv or ical(used for date objects in this project).

Here is a gist with the actions:
https://gist.github.com/cebe/5604091

And this is how a controller uses them:
https://gist.github.com/cebe/5604091#file-myrestcontroller-php

Hope this is good for inspiration and helps finding a good solution :)

@bwoester

This comment has been minimized.

Show comment
Hide comment
@bwoester

bwoester May 18, 2013

Contributor

"Some time ago" made me remember. 😉

Here's my try. It's really work in progress, I did this "some time ago" and then stopped working on it, so it's a bit messy, not completed at all, but hopefully with a few ideas that might the helpful: https://github.com/bwoester/yii-rest-extension

I read through the source and tried to remember how things were meant to work, put that all in the README.md and pushed it.

Contributor

bwoester commented May 18, 2013

"Some time ago" made me remember. 😉

Here's my try. It's really work in progress, I did this "some time ago" and then stopped working on it, so it's a bit messy, not completed at all, but hopefully with a few ideas that might the helpful: https://github.com/bwoester/yii-rest-extension

I read through the source and tried to remember how things were meant to work, put that all in the README.md and pushed it.

@tonydspaniard

This comment has been minimized.

Show comment
Hide comment
@tonydspaniard

tonydspaniard May 23, 2013

Contributor

I experiment on Yiinitializr-advanced boilerplate, and created https://github.com/tonydspaniard/yiinitializr-advanced/tree/master/api/extensions, allowing UrlManager to handle the routing (POST|GET|PUT|DELETE) hope it helps

ps: It only supports Json format

Contributor

tonydspaniard commented May 23, 2013

I experiment on Yiinitializr-advanced boilerplate, and created https://github.com/tonydspaniard/yiinitializr-advanced/tree/master/api/extensions, allowing UrlManager to handle the routing (POST|GET|PUT|DELETE) hope it helps

ps: It only supports Json format

@tjconcept

This comment has been minimized.

Show comment
Hide comment
@tjconcept

tjconcept May 29, 2013

"Native" rest support would be amazing. I think it would be best handled by a new REST application extending \yii\web\Application.

"Native" rest support would be amazing. I think it would be best handled by a new REST application extending \yii\web\Application.

@cebe

This comment has been minimized.

Show comment
Hide comment
@cebe

cebe May 29, 2013

Member

FYI: Created yii\web\VerbFilter yesterday which can be used together with these actions.

Member

cebe commented May 29, 2013

FYI: Created yii\web\VerbFilter yesterday which can be used together with these actions.

@cebe

This comment has been minimized.

Show comment
Hide comment
@cebe

cebe May 30, 2013

Member

Here is a proposal for RESTful routing: https://gist.github.com/cebe/5674918
Will implement changes to UrlManager soon.

Member

cebe commented May 30, 2013

Here is a proposal for RESTful routing: https://gist.github.com/cebe/5674918
Will implement changes to UrlManager soon.

cebe added a commit to cebe/yii2 that referenced this issue May 30, 2013

[WIP] RESTful routing syntax for UrlManager
issue #303
Here is the proposal for RESTful routing syntax:
https://gist.github.com/cebe/5674918
@bwoester

This comment has been minimized.

Show comment
Hide comment
@bwoester

bwoester May 30, 2013

Contributor

Does this proposal for restful routing imply you're concentrating on a solution where each controller implements rest behavior for its own model?

Contributor

bwoester commented May 30, 2013

Does this proposal for restful routing imply you're concentrating on a solution where each controller implements rest behavior for its own model?

@cebe

This comment has been minimized.

Show comment
Hide comment
@cebe

cebe May 30, 2013

Member

Does this proposal for restful routing imply you're concentrating on a solution where each controller implements rest behavior for its own model?

Why should it? Can't see why other approaches should not work then?

Member

cebe commented May 30, 2013

Does this proposal for restful routing imply you're concentrating on a solution where each controller implements rest behavior for its own model?

Why should it? Can't see why other approaches should not work then?

@bwoester

This comment has been minimized.

Show comment
Hide comment
@bwoester

bwoester May 30, 2013

Contributor

Other approaches would still work, sure. The proposal only made me think about pros and cons. For example, activating rest behavior on a per controller level might be easier to get started with.

Contributor

bwoester commented May 30, 2013

Other approaches would still work, sure. The proposal only made me think about pros and cons. For example, activating rest behavior on a per controller level might be easier to get started with.

@cebe

This comment has been minimized.

Show comment
Hide comment
@cebe

cebe May 30, 2013

Member

you mean not using <controller> but explicit name? This would of course work. but for the example I think it is better to show what is possible.
More documentation will of course come to explain all the details and best practices.

Member

cebe commented May 30, 2013

you mean not using <controller> but explicit name? This would of course work. but for the example I think it is better to show what is possible.
More documentation will of course come to explain all the details and best practices.

@bwoester

This comment has been minimized.

Show comment
Hide comment
@bwoester

bwoester May 30, 2013

Contributor

Nope, I didn't mean using <controller> or an explicit controller name.

What I mean is: Most earlier approaches concentrated on a solution with one single controller that is responsible for all REST actions. Only the resource/ model on which the controller operated changed.

Your new proposal seems to suggest handling REST actions in multiple controllers, one for each resource/ model.

Thinking about it, I see both pros and cons. The nice thing is, it is closer to the normal yii request life cycle. People are used to it and thus it will be easy for them to start writing REST backends.

On the other hand, you want have a uniform API for all your REST resources. You want the API to behave equally, regardless of the resource type you're operating on. Examples for this include the ability to accept and respond with different message formats like json or xml. Or to respond with appropriate http headers.

Contributor

bwoester commented May 30, 2013

Nope, I didn't mean using <controller> or an explicit controller name.

What I mean is: Most earlier approaches concentrated on a solution with one single controller that is responsible for all REST actions. Only the resource/ model on which the controller operated changed.

Your new proposal seems to suggest handling REST actions in multiple controllers, one for each resource/ model.

Thinking about it, I see both pros and cons. The nice thing is, it is closer to the normal yii request life cycle. People are used to it and thus it will be easy for them to start writing REST backends.

On the other hand, you want have a uniform API for all your REST resources. You want the API to behave equally, regardless of the resource type you're operating on. Examples for this include the ability to accept and respond with different message formats like json or xml. Or to respond with appropriate http headers.

@cebe

This comment has been minimized.

Show comment
Hide comment
@cebe

cebe May 31, 2013

Member

Yeah, now I see your point. Both variants are good dependent on the situation. I do not concentrate on one of them. Both benefit from this new syntax and this is of course not the most important thing to implement for this issue.

Member

cebe commented May 31, 2013

Yeah, now I see your point. Both variants are good dependent on the situation. I do not concentrate on one of them. Both benefit from this new syntax and this is of course not the most important thing to implement for this issue.

@bobonov

This comment has been minimized.

Show comment
Hide comment
@bobonov

bobonov Jun 7, 2013

Issue 303 and 489 are both closed referencing to each other, is it an error?

bobonov commented Jun 7, 2013

Issue 303 and 489 are both closed referencing to each other, is it an error?

@samdark

This comment has been minimized.

Show comment
Hide comment
@samdark

samdark Jun 7, 2013

Member

303 isn't closed.

Member

samdark commented Jun 7, 2013

303 isn't closed.

@bobonov

This comment has been minimized.

Show comment
Hide comment
@bobonov

bobonov Jun 7, 2013

Sorry my error, I had bot issue open on 2 different tabs, I looked wrongly and posted same message on both.

bobonov commented Jun 7, 2013

Sorry my error, I had bot issue open on 2 different tabs, I looked wrongly and posted same message on both.

@yjeroen

This comment has been minimized.

Show comment
Hide comment
@yjeroen

yjeroen Jun 27, 2013

Some nice reading materialy about Restful services:

yjeroen commented Jun 27, 2013

Some nice reading materialy about Restful services:

@bwoester

This comment has been minimized.

Show comment
Hide comment
@bwoester

bwoester Jul 6, 2013

Contributor

Maybe also interesting: http://restdesc.org/

Contributor

bwoester commented Jul 6, 2013

Maybe also interesting: http://restdesc.org/

@bwoester

This comment has been minimized.

Show comment
Hide comment
@bwoester

bwoester Jul 6, 2013

Contributor

Since there seems to be no standardized way of describing/ documenting a REST API, I think there should be a way to plugin and switch API desc generators.

However, whatever generator you use, the necessary data needs to be defined somewhere. Yii 1.x SOAP implementation did it using annotations in the controller and in used models. Having that data alongside the code helps maintaining it as a project grows and changes.

Contributor

bwoester commented Jul 6, 2013

Since there seems to be no standardized way of describing/ documenting a REST API, I think there should be a way to plugin and switch API desc generators.

However, whatever generator you use, the necessary data needs to be defined somewhere. Yii 1.x SOAP implementation did it using annotations in the controller and in used models. Having that data alongside the code helps maintaining it as a project grows and changes.

@bwoester

This comment has been minimized.

Show comment
Hide comment
@bwoester

bwoester Jul 8, 2013

Contributor

I was unsure whether it is really a good idea to include human readable documentation and examples in an OPTIONS request. After all, the result is meant to be interpreted by a program, isn't it? Nothing a human being would read.

Thinking about what a program can do without human interaction, the first thing I think of is client-side validation. If the OPTIONS request describes the resource and associated messages, this description can be used to validate messages being sent to the server, input errors might be detected before sending them, saving the time needed for the round-trip to the server.

Maybe it could also be used for API versioning, detecting the availability of newer versions or deprecated resources. This could in turn be used to check if newer clients are available and to give the user a hint accordingly.

I also remember an approach that would generate a form for creating and modifying resources given the description of the resource and its attributes. Basically a client side equivalent of yii's form builder.


To make a long story short, I looked at WSDL. I think it's similar to a REST OPTIONS request, since it also describes an available API. IN WSDL, nearly every element supports a documentation element, containing human readable text describing the element. Be it a service, an operation or an error being thrown. [1]

Such information might be used to generate an API description out of the OPTIONS result, or at least to link to an existing documentation/ reference. But I'm still not sure if this is the right way to go.

Does anyone have experience with this?

Contributor

bwoester commented Jul 8, 2013

I was unsure whether it is really a good idea to include human readable documentation and examples in an OPTIONS request. After all, the result is meant to be interpreted by a program, isn't it? Nothing a human being would read.

Thinking about what a program can do without human interaction, the first thing I think of is client-side validation. If the OPTIONS request describes the resource and associated messages, this description can be used to validate messages being sent to the server, input errors might be detected before sending them, saving the time needed for the round-trip to the server.

Maybe it could also be used for API versioning, detecting the availability of newer versions or deprecated resources. This could in turn be used to check if newer clients are available and to give the user a hint accordingly.

I also remember an approach that would generate a form for creating and modifying resources given the description of the resource and its attributes. Basically a client side equivalent of yii's form builder.


To make a long story short, I looked at WSDL. I think it's similar to a REST OPTIONS request, since it also describes an available API. IN WSDL, nearly every element supports a documentation element, containing human readable text describing the element. Be it a service, an operation or an error being thrown. [1]

Such information might be used to generate an API description out of the OPTIONS result, or at least to link to an existing documentation/ reference. But I'm still not sure if this is the right way to go.

Does anyone have experience with this?

@lubosdz

This comment has been minimized.

Show comment
Hide comment
@lubosdz

lubosdz Jul 9, 2013

Contributor

@bwoester Generating human-readable documentation via parsing Docvar blocks is difficult and error-prone. But I dont know other better way:-)

BTW - It's a pity that Yii2 will drop support for SOAP/WSDL because it worked fine. Implementing comments/annotation parser for REST would be actually re-implementing CWsdlGenerator. Would it not be wise to have common annotation parser and use it for JSON/WSDL documentation generator?

Contributor

lubosdz commented Jul 9, 2013

@bwoester Generating human-readable documentation via parsing Docvar blocks is difficult and error-prone. But I dont know other better way:-)

BTW - It's a pity that Yii2 will drop support for SOAP/WSDL because it worked fine. Implementing comments/annotation parser for REST would be actually re-implementing CWsdlGenerator. Would it not be wise to have common annotation parser and use it for JSON/WSDL documentation generator?

@iJackUA

This comment has been minimized.

Show comment
Hide comment
@iJackUA

iJackUA Jul 11, 2013

Contributor

We have build a lot of APIs with Yii framework and had some evolution in it. Definitely SOAP/WSDL is too complicated and harder to maintain. So most of our current API are REST-like with custom routing.

If it could help to push current thread - our biggest concerns was how to make versioned web service ( /v1/action ... ) while keeping native routing nad features of Yii. Currently we are using foloving concept :

  • API is a separate web app
  • controllers are used as Version routers
  • actions are CAction classes (Controller-Version is defining list of supported actions and for example V1 can inherit actions from V2 but overwrite only some of them)
  • little magic with dummy Model and override runWithParams in base action class and we can use native rules() from controller in Action (so each Action has validation rules and can vaildate input parameters with native validators).
  • pagination of collections is made "manually" - so here is a room to automate, but it depends a lot of internal project Core architecture, just a simple use of ActiveRecors will not work everywhere, as in most big projects wit do not use ActiveRecords applciation-wide.

as for Auto Docs - we thought a lot about it also and implemented the idea of some Reflection usage

  • get all controllers - list of available versions
  • iterate by all actions registered in controller - list of supported actions
  • parser rules() per each action - can display in human readable format list of request params , options state, limits, defaults etc. (everything is taken from standard Yii validators).

it is also possible to make auto-generated test GUI for web service that will prepare fields etc - and tester could play with API via GUI interface

What is still left problematic from my point of view - is authorisation and sessions handling, that is still require good thinking to make it really customizable.

I know - all these concepts I have described are quite home-grown and maybe will not work for all, but it could give some new ideas to everyone here.

Contributor

iJackUA commented Jul 11, 2013

We have build a lot of APIs with Yii framework and had some evolution in it. Definitely SOAP/WSDL is too complicated and harder to maintain. So most of our current API are REST-like with custom routing.

If it could help to push current thread - our biggest concerns was how to make versioned web service ( /v1/action ... ) while keeping native routing nad features of Yii. Currently we are using foloving concept :

  • API is a separate web app
  • controllers are used as Version routers
  • actions are CAction classes (Controller-Version is defining list of supported actions and for example V1 can inherit actions from V2 but overwrite only some of them)
  • little magic with dummy Model and override runWithParams in base action class and we can use native rules() from controller in Action (so each Action has validation rules and can vaildate input parameters with native validators).
  • pagination of collections is made "manually" - so here is a room to automate, but it depends a lot of internal project Core architecture, just a simple use of ActiveRecors will not work everywhere, as in most big projects wit do not use ActiveRecords applciation-wide.

as for Auto Docs - we thought a lot about it also and implemented the idea of some Reflection usage

  • get all controllers - list of available versions
  • iterate by all actions registered in controller - list of supported actions
  • parser rules() per each action - can display in human readable format list of request params , options state, limits, defaults etc. (everything is taken from standard Yii validators).

it is also possible to make auto-generated test GUI for web service that will prepare fields etc - and tester could play with API via GUI interface

What is still left problematic from my point of view - is authorisation and sessions handling, that is still require good thinking to make it really customizable.

I know - all these concepts I have described are quite home-grown and maybe will not work for all, but it could give some new ideas to everyone here.

@alexvasilchenko

This comment has been minimized.

Show comment
Hide comment
@alexvasilchenko

alexvasilchenko Jul 11, 2013

Regarding iJackUA's comment:

This engine also supports xml and json formats based on overriding getActionParams() method of CController.

BaseApiController has property

public $formats = array(
'xml' => 'XmlFormatter',
'json' => 'JsonFormatter',
);

that allows to set which class is responsible for each supported format

Each formatting class should implement simple interface

interface IFormatter
{
public function encode($output);
public function decode($input);
public function sendHttpHeaders();
}

This allows us to select one of formats in autodocumentation where we have query emulator.

Would be nice to have something like this in Yii2 natively :)

Regarding iJackUA's comment:

This engine also supports xml and json formats based on overriding getActionParams() method of CController.

BaseApiController has property

public $formats = array(
'xml' => 'XmlFormatter',
'json' => 'JsonFormatter',
);

that allows to set which class is responsible for each supported format

Each formatting class should implement simple interface

interface IFormatter
{
public function encode($output);
public function decode($input);
public function sendHttpHeaders();
}

This allows us to select one of formats in autodocumentation where we have query emulator.

Would be nice to have something like this in Yii2 natively :)

@Ragazzo Ragazzo referenced this issue in yiisoft/yii Jul 20, 2013

Closed

PATCH http requests support in Yii #2664

cebe added a commit that referenced this issue Jul 20, 2013

added support for HTTP verb PATCH
To provider better REST API support PATCH method is added which is used
for partial updates, while a PUT should only update whole record.

issues #303 and yiisoft/yii#2664
@cebe

This comment has been minimized.

Show comment
Hide comment
@cebe

cebe Mar 27, 2014

Member

@githubjeka can you please create a separate issue for that?

Member

cebe commented Mar 27, 2014

@githubjeka can you please create a separate issue for that?

@qiangxue

This comment has been minimized.

Show comment
Hide comment
@qiangxue

qiangxue Mar 27, 2014

Member

Why do you enable csrfValidation for rest api?

Member

qiangxue commented Mar 27, 2014

Why do you enable csrfValidation for rest api?

@cebe

This comment has been minimized.

Show comment
Hide comment
@cebe

cebe Mar 27, 2014

Member

can be a valid thing to enable it when API is consumed by the website itself. i.e. ajax calls use the API that is integrated in the site.

Member

cebe commented Mar 27, 2014

can be a valid thing to enable it when API is consumed by the website itself. i.e. ajax calls use the API that is integrated in the site.

@samdark

This comment has been minimized.

Show comment
Hide comment
@samdark

samdark Mar 27, 2014

Member

Isn't there auth token for the purpose?

Member

samdark commented Mar 27, 2014

Isn't there auth token for the purpose?

@qiangxue

This comment has been minimized.

Show comment
Hide comment
@qiangxue

qiangxue Mar 27, 2014

Member

can be a valid thing to enable it when API is consumed by the website itself. i.e. ajax calls use the API that is integrated in the site.

In that case, an auth token should be obtained by the client first through some process (this is essentially similar to getting csrf token). In general, csrf validation is not needed because rest api should always be validated via auth token.

Member

qiangxue commented Mar 27, 2014

can be a valid thing to enable it when API is consumed by the website itself. i.e. ajax calls use the API that is integrated in the site.

In that case, an auth token should be obtained by the client first through some process (this is essentially similar to getting csrf token). In general, csrf validation is not needed because rest api should always be validated via auth token.

@cebe

This comment has been minimized.

Show comment
Hide comment
@cebe

cebe Mar 27, 2014

Member

agree.

Member

cebe commented Mar 27, 2014

agree.

@githubjeka

This comment has been minimized.

Show comment
Hide comment
@githubjeka

githubjeka Mar 27, 2014

Contributor

Thanks, I wanted to hear it 😄

Contributor

githubjeka commented Mar 27, 2014

Thanks, I wanted to hear it 😄

githubjeka added a commit to githubjeka/angular-yii2 that referenced this issue Mar 28, 2014

@githubjeka

This comment has been minimized.

Show comment
Hide comment
@githubjeka

githubjeka Mar 28, 2014

Contributor

How off

public $authMethods = [
        'yii\rest\HttpBasicAuth',
    ];

for OPTIONS method?

I create demoApp http://angularyii2.github.io/
After authentication I click post and get error

Request Method:OPTIONS
Status Code:401 Unauthorized

I can not control this request options - CORS

Contributor

githubjeka commented Mar 28, 2014

How off

public $authMethods = [
        'yii\rest\HttpBasicAuth',
    ];

for OPTIONS method?

I create demoApp http://angularyii2.github.io/
After authentication I click post and get error

Request Method:OPTIONS
Status Code:401 Unauthorized

I can not control this request options - CORS

@cebe

This comment has been minimized.

Show comment
Hide comment
@cebe

cebe Mar 28, 2014

Member

what exactly is your question?

Member

cebe commented Mar 28, 2014

what exactly is your question?

@githubjeka

This comment has been minimized.

Show comment
Hide comment
@githubjeka

githubjeka Mar 28, 2014

Contributor

How off HttpBasicAuth for OPTIONS method?
OR
How to fix it:
When I send POST, CORS before my POST send own OPTIONS and not send header Authorization.

Contributor

githubjeka commented Mar 28, 2014

How off HttpBasicAuth for OPTIONS method?
OR
How to fix it:
When I send POST, CORS before my POST send own OPTIONS and not send header Authorization.

@qiangxue

This comment has been minimized.

Show comment
Hide comment
@qiangxue

qiangxue Mar 28, 2014

Member

Override yii\rest\Controller::authenticate(), check $action->id and skip options action.

Member

qiangxue commented Mar 28, 2014

Override yii\rest\Controller::authenticate(), check $action->id and skip options action.

@cebe cebe removed the severity:critical label Apr 4, 2014

@subdee subdee referenced this issue Apr 7, 2014

Closed

CORS and REST #3011

@qiangxue qiangxue modified the milestones: 2.0 GA, 2.0 RC Apr 16, 2014

@franciscorangel

This comment has been minimized.

Show comment
Hide comment
@franciscorangel

franciscorangel May 6, 2014

When I use two methods to autenticate, example:

public function behaviors()
    {
        return ArrayHelper::merge(parent::behaviors(), [
            'authenticator' => [
                'class' => CompositeAuth::className(),
                'authMethods' => [
                    \yii\filters\auth\HttpBasicAuth::className(),
                    \yii\filters\auth\HttpBearerAuth::className(),
                ],
            ],
        ]);
    }

HttpBasicAuth and HttpBearerAuth call same method in my class user:

User::findIdentityByAccessToken

I want validate in two different forms, I think is better if Basic and Bearer go to different methods then I don't need to check which autenticate form and I don't need to override anything.

Am I wrong? How is the best way to do it?

When I use two methods to autenticate, example:

public function behaviors()
    {
        return ArrayHelper::merge(parent::behaviors(), [
            'authenticator' => [
                'class' => CompositeAuth::className(),
                'authMethods' => [
                    \yii\filters\auth\HttpBasicAuth::className(),
                    \yii\filters\auth\HttpBearerAuth::className(),
                ],
            ],
        ]);
    }

HttpBasicAuth and HttpBearerAuth call same method in my class user:

User::findIdentityByAccessToken

I want validate in two different forms, I think is better if Basic and Bearer go to different methods then I don't need to check which autenticate form and I don't need to override anything.

Am I wrong? How is the best way to do it?

@qiangxue

This comment has been minimized.

Show comment
Hide comment
@qiangxue

qiangxue May 6, 2014

Member

The format of your access token should be different. You can call different validation methods based on the format in findIdentityByAccessToken.

Member

qiangxue commented May 6, 2014

The format of your access token should be different. You can call different validation methods based on the format in findIdentityByAccessToken.

@franciscorangel

This comment has been minimized.

Show comment
Hide comment
@franciscorangel

franciscorangel May 6, 2014

@qiangxue Thanks for your reply.

If I put on header:
Autorization Bearer AbCdEf123456
Autorization Basic YWRtaW46YWRtaW4=

In the User::findIdentityByAccessToken my token is:
AbCdEf123456, Basic YWRtaW46YWRtaW4=

If I put on header unlike:
Autorization Basic YWRtaW46YWRtaW4=
Autorization Bearer AbCdEf123456

In the User::findIdentityByAccessToken my token is:
admin

I think the order I put on header can't influence on the result.

I don't know if I'm doing something wrong or this expression is wrong:

//HttpBearerAuth->authenticate($user, $request, $response);

preg_match("/^Bearer\\s+(.*?)$/", $authHeader, $matches)

@qiangxue Thanks for your reply.

If I put on header:
Autorization Bearer AbCdEf123456
Autorization Basic YWRtaW46YWRtaW4=

In the User::findIdentityByAccessToken my token is:
AbCdEf123456, Basic YWRtaW46YWRtaW4=

If I put on header unlike:
Autorization Basic YWRtaW46YWRtaW4=
Autorization Bearer AbCdEf123456

In the User::findIdentityByAccessToken my token is:
admin

I think the order I put on header can't influence on the result.

I don't know if I'm doing something wrong or this expression is wrong:

//HttpBearerAuth->authenticate($user, $request, $response);

preg_match("/^Bearer\\s+(.*?)$/", $authHeader, $matches)
@qiangxue

This comment has been minimized.

Show comment
Hide comment
@qiangxue

qiangxue May 6, 2014

Member

Could you create a separate issue about this? Thanks.

Member

qiangxue commented May 6, 2014

Could you create a separate issue about this? Thanks.

@adamaltman

This comment has been minimized.

Show comment
Hide comment
@adamaltman

adamaltman May 16, 2014

Contributor

I'm not clear on the strategy for versioning. Here is an example:

API v1
Resource: car
Attributes: make, model, year

API v2
Resource: car
Months later, we realized we forgot color
Attributes: make, model, year, color.

In this case, we need a migration to add the color column, and a change in the model to validate it. Now, how would we implement v1 and v2? Of course, it's a non-breaking change if color can be null. But, for this example, let's say it must be required when you create POST a car.

I guess there are multiple strategies to doing this -- I'm not clear what the options are, and what may be considered the best approach.

Contributor

adamaltman commented May 16, 2014

I'm not clear on the strategy for versioning. Here is an example:

API v1
Resource: car
Attributes: make, model, year

API v2
Resource: car
Months later, we realized we forgot color
Attributes: make, model, year, color.

In this case, we need a migration to add the color column, and a change in the model to validate it. Now, how would we implement v1 and v2? Of course, it's a non-breaking change if color can be null. But, for this example, let's say it must be required when you create POST a car.

I guess there are multiple strategies to doing this -- I'm not clear what the options are, and what may be considered the best approach.

@iJackUA

This comment has been minimized.

Show comment
Hide comment
@iJackUA

iJackUA May 16, 2014

Contributor

As I understand it is supposed that each developer should implement his own strategy - as it is very specific per each app and each kind of differences between versions. You could have different versions of your Model and keep tack of backward compatibility of them (you can extend v1 from v2 or have completely different classes), have different versions of Components and utility code... so it seems for me very hard to have any generalized way.

Contributor

iJackUA commented May 16, 2014

As I understand it is supposed that each developer should implement his own strategy - as it is very specific per each app and each kind of differences between versions. You could have different versions of your Model and keep tack of backward compatibility of them (you can extend v1 from v2 or have completely different classes), have different versions of Components and utility code... so it seems for me very hard to have any generalized way.

@subdee

This comment has been minimized.

Show comment
Hide comment
@subdee

subdee May 16, 2014

Contributor

General concept is that if you are making breaking changes then you change major version, v1 to v2, but if you are making non-breaking changes you should update minor versions. The docs provide examples on how to do both I think.

In the end, you're free to make your own implementations.

Contributor

subdee commented May 16, 2014

General concept is that if you are making breaking changes then you change major version, v1 to v2, but if you are making non-breaking changes you should update minor versions. The docs provide examples on how to do both I think.

In the end, you're free to make your own implementations.

@Ragazzo

This comment has been minimized.

Show comment
Hide comment
@Ragazzo

Ragazzo Jun 27, 2014

Contributor

Marked testing as complete

Contributor

Ragazzo commented Jun 27, 2014

Marked testing as complete

@Ragazzo

This comment has been minimized.

Show comment
Hide comment
@Ragazzo

Ragazzo Jun 27, 2014

Contributor

@qiangxue is it safe now to implement it on applications with maybe some tests example since Codeception have REST module ?

Contributor

Ragazzo commented Jun 27, 2014

@qiangxue is it safe now to implement it on applications with maybe some tests example since Codeception have REST module ?

@qiangxue

This comment has been minimized.

Show comment
Hide comment
@qiangxue

qiangxue Jun 27, 2014

Member

Yes.

Member

qiangxue commented Jun 27, 2014

Yes.

@qiangxue qiangxue modified the milestones: 2.0.1, 2.0 RC Jul 25, 2014

@fernandezekiel

This comment has been minimized.

Show comment
Hide comment
@fernandezekiel

fernandezekiel Jul 27, 2014

Contributor

for our current design, what's the best way to implement URLs like this one:
POST /accounts/13456/transactions

Contributor

fernandezekiel commented Jul 27, 2014

for our current design, what's the best way to implement URLs like this one:
POST /accounts/13456/transactions

@cebe

This comment has been minimized.

Show comment
Hide comment
@cebe

cebe Jul 27, 2014

Member

@fernandezekiel please open a new issue or ask in the forum or on IRC if it is just a question.
This issue has too much content.
Split it up into #4477 #4478 and #4479.

Member

cebe commented Jul 27, 2014

@fernandezekiel please open a new issue or ask in the forum or on IRC if it is just a question.
This issue has too much content.
Split it up into #4477 #4478 and #4479.

@cebe cebe closed this Jul 27, 2014

@yiisoft yiisoft locked and limited conversation to collaborators Jul 27, 2014

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.