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

POST method instead of GET for ServerSideRender, and JSON representation of attributes #23004

Closed
JohnRDOrazio opened this issue Jun 8, 2020 · 1 comment
Labels
[Package] Server Side Render /packages/server-side-render [Status] Duplicate Used to indicate that a current issue matches an existing one and can be closed

Comments

@JohnRDOrazio
Copy link
Contributor

JohnRDOrazio commented Jun 8, 2020

Is your feature request related to a problem? Please describe.
I ran into a problem using the ServerSideRender component with a fairly large number of attributes: I was getting Error loading block: The response is not a valid JSON response. and the response from the network request was a 502 http status code:

Failed to load resource: the server responded with a status of 502 ()

There are about 60 attributes being passed back and forth using the ServerSideRender component and I see that the attributes are being passed as parameters in the querystring of a GET request. I seem to have finally found the solution to the 502 status code by reconfiguring my nginx server to allow for a larger proxy_buffer_size. But while I have fixed it on my end, I can guess that the problem may popup for other users of my plugin. Here is an example of the request URL being sent:
wp-json/wp/v2/block-renderer/bibleget/bible-quote?context=edit&attributes%5BPARAGRAPHSTYLES_FONTFAMILY%5D=Times%20New%20Roman&attributes%5BPARAGRAPHSTYLES_LINEHEIGHT%5D=1.5&attributes%5BPARAGRAPHSTYLES_PADDINGTOPBOTTOM%5D=8&attributes%5BPARAGRAPHSTYLES_PADDINGLEFTRIGHT%5D=17&attributes%5BPARAGRAPHSTYLES_MARGINTOPBOTTOM%5D=24&attributes%5BPARAGRAPHSTYLES_MARGINLEFTRIGHT%5D=14&attributes%5BPARAGRAPHSTYLES_MARGINLEFTRIGHTUNIT%5D=auto&attributes%5BPARAGRAPHSTYLES_PARAGRAPHALIGN%5D=4&attributes%5BPARAGRAPHSTYLES_WIDTH%5D=85&attributes%5BPARAGRAPHSTYLES_NOVERSIONFORMATTING%5D=false&attributes%5BPARAGRAPHSTYLES_BORDERWIDTH%5D=4&attributes%5BPARAGRAPHSTYLES_BORDERCOLOR%5D=%230b02ac&attributes%5BPARAGRAPHSTYLES_BORDERSTYLE%5D=3&attributes%5BPARAGRAPHSTYLES_BORDERRADIUS%5D=12&attributes%5BPARAGRAPHSTYLES_BACKGROUNDCOLOR%5D=%23fdfbf7&attributes%5BVERSIONSTYLES_BOLD%5D=true&attributes%5BVERSIONSTYLES_ITALIC%5D=true&attributes%5BVERSIONSTYLES_UNDERLINE%5D=false&attributes%5BVERSIONSTYLES_STRIKETHROUGH%5D=false&attributes%5BVERSIONSTYLES_TEXTCOLOR%5D=%23000096&attributes%5BVERSIONSTYLES_FONTSIZE%5D=9&attributes%5BVERSIONSTYLES_FONTSIZEUNIT%5D=inherit&attributes%5BVERSIONSTYLES_VALIGN%5D=3&attributes%5BBOOKCHAPTERSTYLES_BOLD%5D=true&attributes%5BBOOKCHAPTERSTYLES_ITALIC%5D=false&attributes%5BBOOKCHAPTERSTYLES_UNDERLINE%5D=false&attributes%5BBOOKCHAPTERSTYLES_STRIKETHROUGH%5D=false&attributes%5BBOOKCHAPTERSTYLES_TEXTCOLOR%5D=%2302813d&attributes%5BBOOKCHAPTERSTYLES_FONTSIZE%5D=9&attributes%5BBOOKCHAPTERSTYLES_FONTSIZEUNIT%5D=em&attributes%5BBOOKCHAPTERSTYLES_VALIGN%5D=3&attributes%5BVERSENUMBERSTYLES_BOLD%5D=false&attributes%5BVERSENUMBERSTYLES_ITALIC%5D=false&attributes%5BVERSENUMBERSTYLES_UNDERLINE%5D=false&attributes%5BVERSENUMBERSTYLES_STRIKETHROUGH%5D=false&attributes%5BVERSENUMBERSTYLES_TEXTCOLOR%5D=%23ee0000&attributes%5BVERSENUMBERSTYLES_FONTSIZE%5D=7&attributes%5BVERSENUMBERSTYLES_FONTSIZEUNIT%5D=em&attributes%5BVERSENUMBERSTYLES_VALIGN%5D=1&attributes%5BVERSETEXTSTYLES_BOLD%5D=false&attributes%5BVERSETEXTSTYLES_ITALIC%5D=false&attributes%5BVERSETEXTSTYLES_UNDERLINE%5D=false&attributes%5BVERSETEXTSTYLES_STRIKETHROUGH%5D=false&attributes%5BVERSETEXTSTYLES_TEXTCOLOR%5D=%23706e6e&attributes%5BVERSETEXTSTYLES_FONTSIZE%5D=8&attributes%5BVERSETEXTSTYLES_FONTSIZEUNIT%5D=em&attributes%5BVERSETEXTSTYLES_VALIGN%5D=3&attributes%5BLAYOUTPREFS_SHOWBIBLEVERSION%5D=true&attributes%5BLAYOUTPREFS_BIBLEVERSIONALIGNMENT%5D=2&attributes%5BLAYOUTPREFS_BIBLEVERSIONPOSITION%5D=1&attributes%5BLAYOUTPREFS_BIBLEVERSIONWRAP%5D=2&attributes%5BLAYOUTPREFS_BOOKCHAPTERALIGNMENT%5D=1&attributes%5BLAYOUTPREFS_BOOKCHAPTERPOSITION%5D=1&attributes%5BLAYOUTPREFS_BOOKCHAPTERWRAP%5D=1&attributes%5BLAYOUTPREFS_BOOKCHAPTERFORMAT%5D=3&attributes%5BLAYOUTPREFS_BOOKCHAPTERFULLQUERY%5D=false&attributes%5BLAYOUTPREFS_SHOWVERSENUMBERS%5D=true&attributes%5BVERSION%5D%5B0%5D=LUZZI&attributes%5BVERSION%5D%5B1%5D=NVBSE&attributes%5BQUERY%5D=Lc10%2C1-16&attributes%5BPOPUP%5D=false&attributes%5BFORCEVERSION%5D=false&attributes%5BFORCECOPYRIGHT%5D=false&post_id=1178&lang=it&_locale=user
This querystring posted consists of 3082 characters. An nginx server however has a default proxy_buffer_size of 4k, and if you add the COOKIES and other headers it is easy to hit the 4k limit with such a long querystring.

Describe the solution you'd like
As can be seen from the above posted request URL, each attribute is being sent as a parameter of a GET request, thus repeating &attributes[]= for each attribute.

  • I believe the request could be reduced in size by sending a json stringified representation of the attributes. A json stringified representation of the same attributes would consist of 2803 characters. Maybe not a huge difference, but it is something, almost 280 characters less:
    wp-json/wp/v2/block-renderer/bibleget/bible-quote?context=edit&attributes=%7B%22PARAGRAPHSTYLES_FONTFAMILY%22%3A%22Times%20New%20Roman%22%2C%22PARAGRAPHSTYLES_LINEHEIGHT%22%3A1.5%2C%22PARAGRAPHSTYLES_PADDINGTOPBOTTOM%22%3A8%2C%22PARAGRAPHSTYLES_PADDINGLEFTRIGHT%22%3A17%2C%22PARAGRAPHSTYLES_MARGINTOPBOTTOM%22%3A24%2C%22PARAGRAPHSTYLES_MARGINLEFTRIGHT%22%3A14%2C%22PARAGRAPHSTYLES_MARGINLEFTRIGHTUNIT%22%3A%22auto%22%2C%22PARAGRAPHSTYLES_PARAGRAPHALIGN%22%3A4%2C%22PARAGRAPHSTYLES_WIDTH%22%3A85%2C%22PARAGRAPHSTYLES_NOVERSIONFORMATTING%22%3Afalse%2C%22PARAGRAPHSTYLES_BORDERWIDTH%22%3A4%2C%22PARAGRAPHSTYLES_BORDERCOLOR%22%3A%22%230b02ac%22%2C%22PARAGRAPHSTYLES_BORDERSTYLE%22%3A3%2C%22PARAGRAPHSTYLES_BORDERRADIUS%22%3A12%2C%22PARAGRAPHSTYLES_BACKGROUNDCOLOR%22%3A%22%23fdfbf7%22%2C%22VERSIONSTYLES_BOLD%22%3Atrue%2C%22VERSIONSTYLES_ITALIC%22%3Atrue%2C%22VERSIONSTYLES_UNDERLINE%22%3Afalse%2C%22VERSIONSTYLES_STRIKETHROUGH%22%3Afalse%2C%22VERSIONSTYLES_TEXTCOLOR%22%3A%22%23000096%22%2C%22VERSIONSTYLES_FONTSIZE%22%3A9%2C%22VERSIONSTYLES_FONTSIZEUNIT%22%3A%22inherit%22%2C%22VERSIONSTYLES_VALIGN%22%3A3%2C%22BOOKCHAPTERSTYLES_BOLD%22%3Atrue%2C%22BOOKCHAPTERSTYLES_ITALIC%22%3Afalse%2C%22BOOKCHAPTERSTYLES_UNDERLINE%22%3Afalse%2C%22BOOKCHAPTERSTYLES_STRIKETHROUGH%22%3Afalse%2C%22BOOKCHAPTERSTYLES_TEXTCOLOR%22%3A%22%2302813d%22%2C%22BOOKCHAPTERSTYLES_FONTSIZE%22%3A9%2C%22BOOKCHAPTERSTYLES_FONTSIZEUNIT%22%3A%22em%22%2C%22BOOKCHAPTERSTYLES_VALIGN%22%3A3%2C%22VERSENUMBERSTYLES_BOLD%22%3Afalse%2C%22VERSENUMBERSTYLES_ITALIC%22%3Afalse%2C%22VERSENUMBERSTYLES_UNDERLINE%22%3Afalse%2C%22VERSENUMBERSTYLES_STRIKETHROUGH%22%3Afalse%2C%22VERSENUMBERSTYLES_TEXTCOLOR%22%3A%22%23ee0000%22%2C%22VERSENUMBERSTYLES_FONTSIZE%22%3A7%2C%22VERSENUMBERSTYLES_FONTSIZEUNIT%22%3A%22em%22%2C%22VERSENUMBERSTYLES_VALIGN%22%3A1%2C%22VERSETEXTSTYLES_BOLD%22%3Afalse%2C%22VERSETEXTSTYLES_ITALIC%22%3Afalse%2C%22VERSETEXTSTYLES_UNDERLINE%22%3Afalse%2C%22VERSETEXTSTYLES_STRIKETHROUGH%22%3Afalse%2C%22VERSETEXTSTYLES_TEXTCOLOR%22%3A%22%23706e6e%22%2C%22VERSETEXTSTYLES_FONTSIZE%22%3A8%2C%22VERSETEXTSTYLES_FONTSIZEUNIT%22%3A%22em%22%2C%22VERSETEXTSTYLES_VALIGN%22%3A3%2C%22LAYOUTPREFS_SHOWBIBLEVERSION%22%3Atrue%2C%22LAYOUTPREFS_BIBLEVERSIONALIGNMENT%22%3A2%2C%22LAYOUTPREFS_BIBLEVERSIONPOSITION%22%3A1%2C%22LAYOUTPREFS_BIBLEVERSIONWRAP%22%3A2%2C%22LAYOUTPREFS_BOOKCHAPTERALIGNMENT%22%3A1%2C%22LAYOUTPREFS_BOOKCHAPTERPOSITION%22%3A1%2C%22LAYOUTPREFS_BOOKCHAPTERWRAP%22%3A1%2C%22LAYOUTPREFS_BOOKCHAPTERFORMAT%22%3A3%2C%22LAYOUTPREFS_BOOKCHAPTERFULLQUERY%22%3Afalse%2C%22LAYOUTPREFS_SHOWVERSENUMBERS%22%3Atrue%2C%22VERSION%5B0%22%3A%22LUZZI%22%2C%22VERSION%5B1%22%3A%22NVBSE%22%2C%22QUERY%22%3A%22Lc10%2C1-16%22%2C%22POPUP%22%3Afalse%2C%22FORCEVERSION%22%3Afalse%2C%22FORCECOPYRIGHT%22%3Afalse%7D&post_id=1178&lang=it&_locale=user
  • I believe the headers of the request would be much relieved if a POST request were issued rather than a GET request, because the json representation of the attributes would be sent in the body of the request instead of in the headers. Typically the default buffer size for the body of a request / response is 32k (8 * 4k). Considering these issues, I believe it would probably be a much better solution to prefer the POST method to the GET method for these requests. There could be a semantic consideration here about whether the request being made is considered only to retrieve a resource (typical usage of GET for a RESTful resource) or if we could consider a ServerSideRender a kind of generation of a new resource (typical usage of POST for a RESTful resource). In any case we are not dealing with retrieval or creation of database resources, but rather with a complex render which may make use of other server side APIs (such as the Transients API, the Options API... I personally see no problem in using a POST request in this case.
  • I believe we do not need to send ALL attributes to the ServerSideRender callback every time a SINGLE attribute is changed, it could be enough to send only the dirtied or changed attribute, and it would be up to the callback function to handle the representation of the attributes using for example the Options API or similar resources, depending on what needs to be achieved (the value of some attributes may be desirable to apply to all blocks of the same type, whereas the value of other attributes perhaps need be applied only to the current block instance: such things can be handled by the callback function using any APIs that might prove useful to achieve the final result that the callback is trying to achieve)

Describe alternatives you've considered
If we start from the presupposition that users of a plugin should not be required to tune their nginx servers just for a plugin to work correctly, then I don't believe my own solution of changing proxy_buffer_size on my server is a correct solution to this problem. I believe that either the above suggestions should be implemented, and if not I may have to avoid using the ServerSideRender implementation and use my own implementation of ajax requests using POST method.

@JohnRDOrazio JohnRDOrazio changed the title serialization of attributes for ServerSideRender POST method instead of GET for ServerSideRender, and JSON representation of attributes Jun 8, 2020
@ocean90 ocean90 added [Package] Server Side Render /packages/server-side-render [Status] Duplicate Used to indicate that a current issue matches an existing one and can be closed labels Jun 8, 2020
@ocean90
Copy link
Member

ocean90 commented Jun 8, 2020

Hello @JohnRDOrazio, thanks for creating this issue. This request is already being tracked in #19935 with a possible fix in #21068.

@ocean90 ocean90 closed this as completed Jun 8, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Package] Server Side Render /packages/server-side-render [Status] Duplicate Used to indicate that a current issue matches an existing one and can be closed
Projects
None yet
Development

No branches or pull requests

2 participants