2

I'm creating a CakePHP 3.0 REST API. I followed this instructions (routing in the book) and received response in json. Here is my code.

01 src/config/rout.php

Router::extensions('json');

02 src/controler/UsersController.php

  public function view($id = null) {
    $data = array('status' => 'o','status_message' => 'ok' );
    $this->set('data', $data);
    $this->set('_serialize', 'data');  
}

03 send a post request to this URL

http://domain.com/users/view.json

output:

{
    "status": "o",
    "status_message": "ok"
}

But I want to get json out put without .json extension. thank you in advance.

Oops D'oh
  • 941
  • 1
  • 15
  • 34
  • Try to use `Router::parseExtensions('json');` instead of `Router::extensions('json');` ? – Maraboc Nov 02 '15 at 11:48
  • 3
    But, [3-0-migration-guide says](http://book.cakephp.org/3.0/en/appendices/3-0-migration-guide.html) Router::parseExtensions() has been removed. Use Cake\Routing\Router::extensions() instead. This method must be called before routes are connected. It won’t modify existing routes. – Mayura Wijewickrama Nov 03 '15 at 05:32
  • 1
    @Maraboc Any way I don't want to add extension for my URL. I want to out put JSON response without .json extension. – Mayura Wijewickrama Nov 03 '15 at 05:35
  • You need to pass header like `Accept: application/json` and you will get the output as json format. – Khushang Bhavnagarwala. Dec 08 '15 at 08:58

3 Answers3

5

I had same situation but now I found solution for this. Now I can put request url without .json and can get Json data in response as well.

In App controller add network response which will handle your response.

use Cake\Network\Response;

After that you need to convert Json input in array, So put this getJsonInput() function in your AppController and call it in initialize()

public function getJsonInput() {
        $data = file_get_contents("php://input");
        $this->data = (isset($data) && $data != '') ? json_decode($data, true) : array();
    }

Now in your controller, You have all post data in $this->data. so you can access all inputs. Here is an example :

class UsersController extends AppController {

    public function index() {

        if ($this->request->is('post')) {
            //pr($this->data);    //here is your all inputs
           $this->message = 'success';
           $this->status = true;
        }
        $this->respond();
    }
}

Now at the end of your function you need to call respond() which is defined in AppController

public function respond() {  
        $this->response->type('json');  // this will convert your response to json
        $this->response->body([
                    'status' => $this->status,
                    'code' => $this->code,
                    'responseData' => $this->responseData,
                    'message'=> $this->message,
                    'errors'=> $this->errors,
                ]);   // Set your response in body
        $this->response->send();  // It will send your response
        $this->response->stop();  // At the end stop the response
    }

Define all variable in the AppController as

public $status = false;
public $message = '';
public $responseData = array();
public $code = 200;
public $errors = '';

One more thing to do is:

In the Response.php (/vendor/cakephp/cakephp/src/Network/Response.php) You need to edit one line at 586 echo $content; to echo json_encode($content); in _sendContent() function.

That's it. Now you can set request url as domain_name/project_name/users/index.

Pooja Yadav
  • 91
  • 1
  • 3
1

If someone still looking for easy json response solution here is a quick one :

add this method to your AppController.php

public function jsonResponse($responseData = [], $responseStatusCode = 200) {

    Configure::write('debug', 0);

    $this->response->type('json');
    $this->response->statusCode($responseStatusCode);
    $this->response->body(json_encode($responseData));
    $this->response->send();
    $this->render(false,false);

}

and you can use it in any action as simple as that

$data = ['status' => 'ok', 'foo' => 'bar'];
$this->jsonResponse($data);

and another example

$data = ['status' => 'failed', 'bar' => 'foo'];
$this->jsonResponse($data, 404);

hope that helps :)

Medo
  • 418
  • 7
  • 11
0

Request your data with a proper HTTP accept header Accept: application/json, the RequestHandler should pick it up then.

The Accept header is used by HTTP clients to tell the server what content types they'll accept. The server will then send back a response, which will include a Content-Type header telling the client what the content type of the returned content actually is.

However, as you may have noticed, HTTP requests can also contain Content-Type headers. Why? Well, think about POST or PUT requests. With those request types, the client is actually sending a bunch of data to the server as part of the request, and the Content-Type header tells the server what the data actually is (and thus determines how the server will parse it).

In particular, for a typical POST request resulting from an HTML form submission, the Content-Type of the request will normally be either application/x-www-form-urlencoded or multipart/form-data.

Community
  • 1
  • 1