Search code examples
jsonrestzend-framework2laminas-api-toolshal-json

How to enable Json pretty print on Apigility ApiProblem response?


I would like to know how to set ApiProblem response to pretty print Json by default.


Solution

  • I've made a few changes on class ApiProblemResponse. I set the property $jsonFlags to 128, which is related to JSON_PRETTY_PRINT code.

    Here's the full class code with my changes:

    <?php
    
    namespace Zend\ApiProblem;
    
    use Zend\Http\Response;
    
    /**
     * Represents an ApiProblem response payload
     */
    class ApiProblemResponse extends Response
    {
        /**
         * @var ApiProblem
         */
        protected $apiProblem;
    
        /**
         * Flags to use with json_encode JSON_PRETTY_PRINT
         *
         * @var int
         */
        protected $jsonFlags = 128;
    
        /**
         * @param ApiProblem $apiProblem
         */
        public function __construct(ApiProblem $apiProblem)
        {
            $this->apiProblem = $apiProblem;
            $this->setCustomStatusCode($apiProblem->status);
            $this->setReasonPhrase($apiProblem->title);
    
            // Just comment/remove these lines to prevent flags from being overwrited
            //if (defined('JSON_UNESCAPED_SLASHES')) {
              //$this->jsonFlags = constant('JSON_UNESCAPED_SLASHES');
            //}
        }
    
        /**
         * @return ApiProblem
         */
        public function getApiProblem()
        {
            return $this->apiProblem;
        }
    
        /**
         * Retrieve the content
         *
         * Serializes the composed ApiProblem instance to JSON.
         *
         * @return string
         */
        public function getContent()
        {
    
            return json_encode($this->apiProblem->toArray(), $this->jsonFlags);
        }
    
        /**
         * Retrieve headers
         *
         * Proxies to parent class, but then checks if we have an content-type
         * header; if not, sets it, with a value of "application/problem+json".
         *
         * @return \Zend\Http\Headers
         */
        public function getHeaders()
        {
            $headers = parent::getHeaders();
            if (!$headers->has('content-type')) {
                $headers->addHeaderLine('content-type', 'application/problem+json');
            }
            return $headers;
        }
    
        /**
         * Override reason phrase handling
         *
         * If no corresponding reason phrase is available for the current status
         * code, return "Unknown Error".
         *
         * @return string
         */
        public function getReasonPhrase()
        {
            if (! empty($this->reasonPhrase)) {
                return $this->reasonPhrase;
            }
    
            if (isset($this->recommendedReasonPhrases[$this->statusCode])) {
                return $this->recommendedReasonPhrases[$this->statusCode];
            }
    
            return 'Unknown Error';
        }
    }
    

    Inside my controller i used:

    return new ApiProblemResponse(
      new ApiProblem(ApiProblemResponse::STATUS_CODE_501, 'Example of JSON_PRETTY_PRINT response.')
    );
    

    And did the trick:

    {
        "type": "http:\/\/www.w3.org\/Protocols\/rfc2616\/rfc2616-sec10.html",
        "title": "Not Implemented",
        "status": 501,
        "detail": "Example of JSON_PRETTY_PRINT response."
    }