Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[FrameworkBundle] [DX] Add Controller::json method to make it easy to send json #17642

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

Merged
merged 1 commit into from
Mar 3, 2016

Conversation

mcfedr
Copy link
Contributor

@mcfedr mcfedr commented Feb 1, 2016

Q A
Bug fix? no
New feature? yes
BC breaks? no
Deprecations? no
Tests pass? yes
Fixed tickets
License MIT
Doc PR

Its currently a awkward to use Serializer component to send a JsonResponse.

I have tried two approaches

  1. use Serializer::normalize and JsonResponse
  2. use Serializer::serialize and a plain Response, and set the content-type

In either cases there is need for a custom json function so as not to repeat yourself and there are disadvantages.

  1. In the first case you are only partly using Serializer and any custom Encoder would be skipped
  2. In the second you are not making use of JsonResponse, particular disadvantage if you want to support JSONP.

This new json method uses the serializer component is enabled it is used to generate the json data, and falls back to normal JsonResponse when its not.

*/
public function setContext(array $context)
{
$this->context = $context;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is broken in case you call the setter after setting data

@dunglas
Copy link
Member

dunglas commented Feb 1, 2016

Why not something like https://github.com/dunglas/DunglasApiBundle/blob/1.x/Controller/ResourceController.php#L79-L93?

I agree with @stof, Response should be a value object. The serializer should not be injected in it. An helper method in the controller like this one API Platform would be better IMO. Btw, we should wait for a decision about #16863 before adding new methods to the controller IMO.

@mcfedr mcfedr force-pushed the add-controller-json branch from fe42ab8 to 11bc151 Compare February 1, 2016 20:40
@mcfedr
Copy link
Contributor Author

mcfedr commented Feb 1, 2016

Now I look at it again, I completely agree on the weirdness of inserting the Serializer into the Response.

How about what I have done now? Its very similar to how DunglasApiBundle does it, but keeping the JsonResponse.

*
* @return JsonResponse
*/
protected function json($data, $status = 200, $headers = array(), $context = array())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about renderJson or something similar to existing methods?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

json is consistent with stream to return a stream response.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was looking at redirect and stream as similar names, also renderView for example returns a string, not a Response

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok :)

@mcfedr
Copy link
Contributor Author

mcfedr commented Feb 1, 2016

@dunglas That was a long read! Would certainly wait until a decision is made there. I see some real value in breaking up an every growing Controller class.

@mcfedr mcfedr force-pushed the add-controller-json branch 3 times, most recently from 273a896 to ecd3587 Compare February 5, 2016 08:07
@fabpot
Copy link
Member

fabpot commented Feb 29, 2016

LGTM. ping @symfony/deciders

'json_encode_options' => JsonResponse::DEFAULT_ENCODING_OPTIONS,
), $context));

return new JsonResponse($json, $status, $headers, true);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fourth argument should be removed.

Sorry, I missed the change below.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But you now have to increase the required version of symfony/http-foundation.

@@ -22,7 +22,7 @@
"symfony/dependency-injection": "~2.8|~3.0",
"symfony/config": "~2.8|~3.0",
"symfony/event-dispatcher": "~2.8|~3.0",
"symfony/http-foundation": "~2.8|~3.0",
"symfony/http-foundation": "~3.1",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@xabbuh is this the best way to do it? I see at least one other component has a ~3.0 requirement, I assume this is expected to change as new functionality is added to Symfony 3

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, that's right

@mcfedr
Copy link
Contributor Author

mcfedr commented Mar 1, 2016

@xabbuh Does anything else need to be done?

@mcfedr mcfedr force-pushed the add-controller-json branch from c37096a to d4511eb Compare March 1, 2016 12:04
protected $encodingOptions = 15;
const DEFAULT_ENCODING_OPTIONS = 15;

protected $encodingOptions = self::DEFAULT_ENCODING_OPTIONS;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IRC, the possibility to assign a property from a constant value is available only on php >= 5.6, and Sf3 is php >= 5.5...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I can tell this usage has always been part of PHP 5. It certainly works in 5.5. You made me doubt it and I ran the tests for this class in 5.5 to double check!

I know that from PHP 7 its possible to write this how I would have really liked

const DEFAULT_ENCODING_OPTIONS = JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ow, yeah I may have mistaken with arithmetics such as const DEFAULT_ENCODING_OPTIONS = JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT indeed. My bad !

@xabbuh
Copy link
Member

xabbuh commented Mar 1, 2016

👍

@mcfedr
Copy link
Contributor Author

mcfedr commented Mar 1, 2016

@xabbuh does the 'needs work' label still need to be here?

@xabbuh
Copy link
Member

xabbuh commented Mar 1, 2016

@mcfedr No, you're right.

Status: Reviewed

3.1.0
-----

* Added `Controller:json` to simplify creating JSON responses when using the Serializer component
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo: missing double colon

If the serializer component is enabled it is used to generate the json
data, if not the standard `json_encode`  function is used
@mcfedr mcfedr force-pushed the add-controller-json branch from d4511eb to f904a2b Compare March 2, 2016 14:31
@javiereguiluz javiereguiluz added Feature FrameworkBundle DX DX = Developer eXperience (anything that improves the experience of using Symfony) labels Mar 3, 2016
@fabpot
Copy link
Member

fabpot commented Mar 3, 2016

Thank you @mcfedr.

@fabpot fabpot merged commit f904a2b into symfony:master Mar 3, 2016
fabpot added a commit that referenced this pull request Mar 3, 2016
…o make it easy to send json (mcfedr)

This PR was merged into the 3.1-dev branch.

Discussion
----------

[FrameworkBundle] [DX] Add `Controller::json` method to make it easy to send json

| Q             | A
| ------------- | ---
| Bug fix?      | no
| New feature?  | yes
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets |
| License       | MIT
| Doc PR        |

Its currently a awkward to use Serializer component to send a `JsonResponse`.

I have tried two approaches

1. use `Serializer::normalize` and `JsonResponse`
1. use `Serializer::serialize` and a plain `Response`, and set the `content-type`

In either cases there is need for a custom `json` function so as not to repeat yourself and there are disadvantages.

1. In the first case you are only partly using `Serializer` and any custom `Encoder` would be skipped
1. In the second you are not making use of `JsonResponse`, particular disadvantage if you want to support JSONP.

This new `json` method uses the serializer component is enabled it is used to generate the json data, and falls back to normal `JsonResponse` when its not.

Commits
-------

f904a2b Add a Controller function to make it easy to return json
@taylorotwell
Copy link
Contributor

This breaks BC by adding a new property to public setData method of JsonResponse, which Laravel overrides.

*
* @return JsonResponse
*
* @throws \InvalidArgumentException
*/
public function setData($data = array())
public function setData($data = array(), $preEncoded = false)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Breaks BC.

@weaverryan
Copy link
Member

I agree - it looks like this violates our BC policy - http://symfony.com/doc/current/contributing/code/bc.html#changing-classes - sub-item "Public Methods -> Add argument with a default value". I don't think we allow a change like this.

@dunglas
Copy link
Member

dunglas commented Mar 4, 2016

What we can do instead is adding a new public setPreEncoded method.

@nicolas-grekas
Copy link
Member

Or "setJson" :-) which should be called by setData internally btw

@fabpot
Copy link
Member

fabpot commented Mar 4, 2016

I think the setJson() method is indeed a good solution. @nicolas-grekas Can you work on a PR?

fabpot pushed a commit that referenced this pull request Mar 4, 2016
fabpot added a commit that referenced this pull request Mar 4, 2016
This PR was squashed before being merged into the 3.1-dev branch (closes #18006).

Discussion
----------

[HttpFoundation] Fix BC break introduced by #17642

| Q             | A
| ------------- | ---
| Branch        | master
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #17642
| License       | MIT
| Doc PR        | n/a

@taylorotwell can you confirm it fixes the issue with Laravel?

Commits
-------

73ef995 [HttpFoundation] Fix BC break introduced by #17642
3.1.0
-----

* Added `Controller::json` to simplify creating JSON responses when using the Serializer component
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing [BC break] ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAIK, it's not a BC break.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, sorry I got confused by #18373.

fabpot added a commit that referenced this pull request Apr 5, 2016
…n() method (derrabus)

This PR was merged into the 3.1-dev branch.

Discussion
----------

[FrameworkBundle] Upgrade notice for the Controller::json() method

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | N/A
| License       | MIT
| Doc PR        | N/A

PR #17642 added a `json()` method to the `Controller` class. This might break existing code extending the class. This PR adds a note about this to the UPGRADE-3.1 document.

Commits
-------

ca6694a Upgrade notice for the Controller::json() method.
@avtehnik
Copy link

Awsome!

@Etheriq
Copy link

Etheriq commented Apr 20, 2016

nice job, Fred!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
DX DX = Developer eXperience (anything that improves the experience of using Symfony) Feature FrameworkBundle Status: Reviewed
Projects
None yet
Development

Successfully merging this pull request may close these issues.