Luracast Restler: “Naming” returned objects

2019-05-24 23:35发布

问题:

I'm using the nice Restler REST framework to expose some resources in a database to various clients.

Now when returning results from service, the format is somewhat like this (I'm using the Restler web sites own examples as a basis here):

[
 {
   "id": 1,
   "name": "Jac Wright",
   "email": "jacwright@gmail.com"
 }
]

Or in XML:

<?xml version="1.0"?>
<response>
  <item>
    <id>1</id>
    <name>Jac Wright</name>
    <email>jacwright@gmail.com</email>
  <item>
</response>

What bugs me a little is that in JSON the structure is anonymous (if that is the correct term to use here?) and that in the XML the object is wrapped in an "item" tag. I'd like to see the structure returned wrapped by the resource type name. Like this:

[
 "author": {
   "id": 1,
   "name": "Jac Wright",
   "email": "jacwright@gmail.com"
 }
]

and

<?xml version="1.0"?>
<response>
  <author>
    <id>1</id>
    <name>Jac Wright</name>
    <email>jacwright@gmail.com</email>
  <author>
</response>

In case I haven't completely grokked the relevant code, is this at all possible without modding Restler itself?

回答1:

The example you have pointed out returns the following

return array(
    array('id'=>1,  'name'=>'Jac Wright',   'email'=>'jacwright@gmail.com'),
    array('id'=>2,  'name'=>'Arul Kumaran', 'email'=>'arul@luracast.com'  ),
);

all we need to do is wrap the individual arrays in another array under the key 'author'. For example in author.php

<?php
class Author {
    function post ($request_data){
        print_r($request_data);
        return $request_data;
    }
    function get() {
        return array('author'=> array(
                    array('id'=>1,  'name'=>'Jac Wright1', 'email'=>'jacwright@gmail.com'),
                    array('id'=>2,  'name'=>'Arul Kumaran3','email'=>'arul@luracast.com')
               ));
    }
}

This gets the exact result that you wanted for both json and xml

author.xml:

<?xml version="1.0"?>
<response>
  <author>
    <id>1</id>
    <name>Jac Wright1</name>
    <email>jacwright@gmail.com</email>
  </author>
  <author>
    <id>2</id>
    <name>Arul Kumaran3</name>
    <email>arul@luracast.com</email>
  </author>
</response>

author.json:

{
  "author": [
    {
      "id": 1,
      "name": "Jac Wright1",
      "email": "jacwright@gmail.com"
    },
    {
      "id": 2,
      "name": "Arul Kumaran3",
      "email": "arul@luracast.com"
    }
  ]
}

Let me explain the technique that I used as well, I used the above post method and posted the exact xml structure I want and used print_r to find the corresponding php structure :)

Here is the cURL I tried in the command line

curl -X POST http://restler2.dev/test/naming_returned/author.xml -H "Content-Type: text/xml" -d '<response><author><id>1</id><name>Jac Wright</name><email>jacwright@gmail.com</email></author><author><id>1</id><name>Jac Wright</name><email>jacwright@gmail.com</email></author></response>'

and the response

Array
(
    [author] => Array
        (
            [0] => Array
                (
                    [id] => 1
                    [name] => Jac Wright
                    [email] => jacwright@gmail.com
                )

            [1] => Array
                (
                    [id] => 1
                    [name] => Jac Wright
                    [email] => jacwright@gmail.com
                )

        )

)
<?xml version="1.0"?>
<response>
  <author>
    <id>1</id>
    <name>Jac Wright</name>
    <email>jacwright@gmail.com</email>
  </author>
  <author>
    <id>1</id>
    <name>Jac Wright</name>
    <email>jacwright@gmail.com</email>
  </author>
</response>

For completeness let me put the gateway index.php as well here

<?php
require_once '../../restler/restler.php';

#set autoloader
#do not use spl_autoload_register with out parameter
#it will disable the autoloading of formats
spl_autoload_register('spl_autoload');

$r = new Restler();
$r->addAPIClass('Author');
$r->setSupportedFormats('JsonFormat','XmlFormat');
$r->handle();


标签: php api rest