Warning: Can't synchronize with repository "(default)" (Unsupported version control system "svn": No module named svn). Look in the Trac log for more information.

Ticket #1459 (closed defect: fixed)

Opened 10 years ago

Last modified 9 years ago

Need a consistent way to request JSON output

Reported by: abadger1999 Owned by: anonymous
Priority: normal Milestone:
Component: TurboGears Version: 1.0.3
Severity: normal Keywords: jsonify, json
Cc:

Description

Currently, using the two forms of expose create different URLs for retrieving JSON::

@expose(allow_json=True) => URL/?tg_format=json @expose('json') => URL/ And tg_format=json is an error.

This makes it hard for client code that doesn't care how the server is implemented, it just wants to retrieve json data from the server. The easy way to deal with this is to allow both forms of expose to create a function that accepts tg_format=json.

Change History

comment:1 follow-up: ↓ 2 Changed 10 years ago by Chris Arndt

1) You can set tg.allow_json to True in your project's app.cfg file to allow tg_format=json for all exposed methods.

2) I think, you need rethink your app's URL interface. Either an exposed method always returns JSON, then the client-side JS should know this and use a URL without tg_format=json, or the method can return JSON and something else (HTML), then the server needs something to distinguish between request for the two return data formats. You have the control over the client code, so why can't you specify which resource you want to request?

3) You can also use the Accept request header to specify the return data format:

 http://docs.turbogears.org/1.0/ExposeDecorator#id3

I'm inclined to resolve this ticket as "wontfix". Convince us, if you disagree.

comment:2 in reply to: ↑ 1 Changed 10 years ago by abadger1999

Replying to Chris Arndt:

1) You can set tg.allow_json to True in your project's app.cfg file to allow tg_format=json for all exposed methods.

This is a true statement but not what I'm asking for. There should still be URLs that are not accessible via JSON.

2) I think, you need rethink your app's URL interface. Either an exposed method always returns JSON, then the client-side JS should know this and use a URL without tg_format=json, or the method can return JSON and something else (HTML), then the server needs something to distinguish between request for the two return data formats. You have the control over the client code, so why can't you specify which resource you want to request?

I think your assumption is wrong. Why should the client code need to know that specifying tg_format=json is illegal? Why does it need to know that a particular URL always or sometimes returns JSON? The server cares because it needs to know whether it's supposed to deliver html or JSON but all the client cares is that it makes a request and gets data back in the format it desires. Why should the client care that it *must* specify:

 http://localhost:8080/json_only_data/  http://localhost:8080/html_or_json/?tg_format=json

The client should be able to specify

 http://localhost:8080/json_only_data/?tg_format=json  http://localhost:8080/html_or_json/?tg_format=json

and if the server has an @expose that handles json, then it will do the right thing. Making it so the second case doesn't work adds an unnecessary extra piece of information for the client to deal with. If the server suddenly stops providing an html view of the data at the same URL, it will break the client even though, for the client, nothing has changed.

Also, this is even more inconsistent than I first thought: These cases take a tg_format query param::

@expose('templates.welcome', allow_json=True) def public_method(self):

@expose(allow_json=True) def public_method(self):

@expose('templates.welcome') @expose('json') def public_method(self):

This case does not:

@expose('json') def public_method(self):

So it looks like the single expose decorator is a special case. Why do you think it is necessary for the server to disallow tg_format=json in this case?

3) You can also use the Accept request header to specify the return data format:

 http://docs.turbogears.org/1.0/ExposeDecorator#id3

While using the accept header is fine for writing into my client library routine, it is harder to test that the server is behaving when you have to inject a header rather than specifying a simple query param on the commandline. It's also harder for an end user creating a third party script that supplements whatever I'm officially providing to discover and use.

comment:3 Changed 9 years ago by Chris Arndt

  • Keywords jsonify, json added

comment:4 Changed 9 years ago by chrisz

  • Status changed from new to closed
  • Resolution set to fixed

I think this makes sense. Fixed in r4727.

Note: See TracTickets for help on using tickets.