REST Response in multiple formats

96 views
Skip to first unread message

Anatol Buchholz

unread,
Dec 28, 2016, 12:28:00 PM12/28/16
to f3-fra...@googlegroups.com
Hi,

this nice e-book says:

We recommend that you support more than one format - that you push things out in one format and accept as many formats as necessary. You can usually automate the mapping from format to format. ... We recommend the fourthsquare approach To get the JSON format from a collection or specific element:
dogs.json
/dogs/1234.json


For me this means checking which ending the request has and return either json or xml:


class Item {

    var $outformat = 'json',
    $content = NULL;

    function __construct($f3){
if ( strpos(basename($f3->get('PATH')),'.xml') )
        $this->outformat='xml'; 
    }

    function get($f3) {
    $this->content = array ('black' => 'dog','white' => 'sheep');
    }

    function post(){}

    function put(){}

    function delete(){}

    function afterroute (){

    if($this->outformat == 'xml'){
header('Content-Type: text/xml');
    $xml = new SimpleXMLElement('<root/>');
array_walk_recursive($this->content, array ($xml, 'addChild'));
    die(print $xml->asXML());
    }

    header('Content-Type: application/json');
    die(json_encode($this->content));
    }
}

$f3->map('/cart/@item','Item');


My questions, 

  • is there some F3 var which already holds the extension of the last param (.json || .xml) [see constructor]?
  • is there a better (F3´ish) pattern than this with __construct and afterroute()
cheers and of course ... merry christmas!

- anatol


ved

unread,
Dec 28, 2016, 3:42:01 PM12/28/16
to Fat-Free Framework
Hi, 
  • is there some F3 var which already holds the extension of the last param (.json || .xml) [see constructor]?
I don't think so, but when in doubt I find that a good old print_r($f3->hive()) really helps to see what's available in the hive. 
But anyway, there's several ways to do this and yours seems like a perfectly valid option.
Some alternatives are:
- using http headers (you can maybe use HEADERS.Accept from f3?).
- default to one specific format and require the client to use a parameter for other formats (e.g.: ?format=xml)
- different api endpoints like /v1/something/json, /v1/something/xml
- etc?
  • is there a better (F3´ish) pattern than this with __construct and afterroute() 
This approach seems fine. You can maybe create a parent BaseApi class with a beforeroute (instead of the constructor) and afterroute then have your api classes extend that?

cheers


Anatol Buchholz

unread,
Dec 28, 2016, 6:17:44 PM12/28/16
to Fat-Free Framework
thanks a lot for your input ved!

print_r($f3->hive())

nice! I was searching in f3/lib for answers.
I´m unsure if a xml response is really needed as the book suposses.
Maybe for the small thing I´m planing json only is okay.
but it´s good practice to get into REST.

cheers,

– a

bcosca

unread,
Dec 28, 2016, 8:26:29 PM12/28/16
to Fat-Free Framework
Other formats you may want to consider aside from JSON would be CSV, XML, including YAML and some other markup.

Anatol Buchholz

unread,
Dec 29, 2016, 6:51:37 AM12/29/16
to f3-fra...@googlegroups.com
Thanks Bong and Ved!

you can maybe create a parent BaseApi class with a beforeroute (instead of the constructor) and afterroute then have your api classes extend that?

This sounds like a nice plugin idea. 
It could return formats bong mentioned and also respect what the e-book suggests here:

When a client intercepts HTTP error codes
 
1 - Use suppress_response_codes = true
2 - The HTTP code is no longer just for the code 
3 - Push any response code that we would have put in the HTTP response down into the response message 

 
Can one assume that a REST response can be generalized as (nested) assoc array? – Or is the 
returned (format) application specific? (In this case a plugin would not make much sense ...)

ved

unread,
Dec 29, 2016, 9:45:29 AM12/29/16
to Fat-Free Framework
Personally, I wouldn't bother with other formats besides json unless your service will in fact be used by people that really have to use xml or some other format. Most languages these days have the ability to parse json just fine so it shouldn't really be an issue for most people. Also, most api's (at least the ones I've been using these past years) return in json.

Of course that depending on what you're returning on your api, some other format may be more adequate, including the ones stated by Bong as well as other optimized formats like msgpack or even some kind of binary format (?).

As for your last question, I'm guessing that while there's certainly a good deal of "best practices" when developing api's, it all depends on what exactly the api does. That said, some industries may have specifications for these types of things.

For example, if you're doing something to integrate with the travel/hospitality industry (hotels, flights, rent a cars, etc), there is a set of XML Schemas defined by the Open Travel Alliance that were developed specifically so those types of companies can better intercommunicate between them. (So, when you go to a site that gets prices or availability for hotels, flights, etc, they're most likely communicating with each other through an OTA compliant API). Side note: I've done some work integrating an OTA compliant API using PHP and it wasn't a pleasant experience. Still, they've been in use for over a decade by multiple billion dollar companies with great success and it's pretty much a vital component of that sector.
Other specific industries may define their own "recommendation" in order to facilitate exchanges across their sector.

I wasn't aware of any specification or recommendation regarding the format of the returned data structures for json api's but found this on the web that may help. (I haven't read it)

You should also take a look at the documentation of several proven public api's from big companies and get some more insight from those.

Here are some popular examples:

JSON APIs:

XML and XML-RPC APIs:

Hope it helps. My suggestion is to make your api as simple as possible (but not simpler) and easy to adopt by developers.

cheers.




Anatol Buchholz

unread,
Dec 29, 2016, 12:20:52 PM12/29/16
to Fat-Free Framework
Dear ved,

thanks a lot for your detailed answer, especially for the links.
They will help me to get a feeling what can be done with REST

... all the best for the last days in 2016 ;)

– anatol

ved

unread,
Dec 29, 2016, 12:32:39 PM12/29/16
to Fat-Free Framework
No problem Anatol, glad it helped.

Good luck and happy new year

xfra35

unread,
Dec 31, 2016, 1:30:12 AM12/31/16
to f3-fra...@googlegroups.com
Hi Anatol,

is there some F3 var which already holds the extension of the last param?

You can use PARAMS if you declare the extension in your routes:

[maps]
/dogs.@ext = Controllers\Dogs

Then in your afterroute:

function afterroute($f3,$params) {
 
switch($params['ext']) {
   
case 'json':
     
// output json
   
case 'xml':
     
// output xml
   
default:
      $f3
->error(404);
 
}
}



Anatol Buchholz

unread,
Dec 31, 2016, 11:05:55 AM12/31/16
to Fat-Free Framework
Ahhh xfra, 

nice, really nice!

thanks.

Summer White

unread,
Jan 1, 2017, 3:48:09 AM1/1/17
to Fat-Free Framework
Blew my mind just now.
Reply all
Reply to author
Forward
0 new messages