2
\$\begingroup\$

I'm implementing a REST API in PHP 7.1. It is designed to throw Exceptions to print non-200 responses.

I decided to go with the following:

abstract class APIException extends \Exception
{
    public function __construct($message, $code, Exception $previous = null) {
        parent::__construct($message, $code, $previous);
    }

    public function parseException() {
        return ResponseParser::parseResponse($this->message, $this->code);
    }
}

And then I extended the BaseException with my various personal exceptions, like IncorrectMethodException here.

class IncorrectMethodException extends APIException
{
    public function __construct(String $expectedMethod, Exception $previous = null) {
        parent::__construct("Incorrect method, $expectedMethod expected", 405, $previous);
    }
}

Here is the code to my ResponseParser class:

class ResponseParser
{
    /**
     * @param $data
     * @param int $status
     * @return string
     */
    public static function parseResponse($data, $status = 200)
    {
        header("Access-Control-Allow-Origin: *");
        header("Access-Control-Allow-Methods: *");
        header("Content-Type: application/json");
        header("HTTP/1.1 " . $status . " " . self::_requestStatus($status));
        return json_encode($data);
    }

    /**
     * @param $code
     * @return string status code
     */
    private static function _requestStatus($code)
    {
        $status = array(
            200 => 'OK',
            400 => 'Bad Request',
            401 => 'Unauthorized',
            404 => 'Not Found',
            405 => 'Method Not Allowed',
            500 => 'Internal Server Error',
        );
        return ($status[$code]) ? $status[$code] : $status[500];
    }
}

Is this a correct way to avoid code duplication here?

\$\endgroup\$
0

1 Answer 1

3
\$\begingroup\$

Naming:

  • ResponseParser doesn't actually parse a response. Parsing a response would mean taking some response object and extracting data from it. This class does the opposite - given some data, it generates HTTP response.

Separation of concerns:

  • Exception classes are aware of how to output themselves as HTTP response. Would be better to structure things the other way around: passing the exception object to ResponseParser that generates the HTTP response.

Side-effects:

  • parseResponse() outputs HTTP headers and returns JSON. It's confusing when function has a return value and it also generates some output. I would it to expect to also output the JSON as the response, or returning both headers data and JSON without causing any side-effects.
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.