Question

I have a PHP REST API written with CakePHP as part of a project. All of the API endpoints exist as individual methods in controllers and accept arguments and return values in a JSON string. I am trying to figure how I should document the parameters and return types for these methods phpDocumentor2.

For example, if I have a edit() method in UsersController that updates specified fields for the User model, whose skeleton looks like this (I've simplified the code for brevity):

public function edit() {
    //Get arguments
    $args = $this->request->data['args'];
    $id = $args['id'];

    //Perform processing
    if (!$this->User->exists($id)) {
        $data = $this->createError(300);
    }
    else {
        $this->User->id = $id;

        $saveData = array();

        if (isset([$args['first_name'])) {
          $saveData['User']['first_name'] = $args['first_name'];
        }

        if (isset([$args['last_name'])) {
          $saveData['User']['last_name'] = $args['last_name'];
        }

        $isSaved = $this->User->save($saveData);

        if (count($this->User->validationErrors) > 0) {
            $data = $this->createError(202, $this->User->validationErrors);
        }
        else {
            $data = array('status' => $isSaved ? 1 : 0);
        }
    }

    //Output data
    return $data;
}

I might send a request with the following JSON to modify the user's first and last names.:

{
    "id": 1
    "first_name": "John"
    "last_name": "Doe"
}

If the API call is successful, the method will return:

{
    "status": 1
}

And if it is unsuccessful, perhaps to due to failed data validation, the method might return something like:

{
    "status": 0
    "code": 202,
    "messages": {
        "first_name": {
            "Numeric characters are not allowed."
        }
    }
}

I understand that I can use phpDocumentor's @return and @param to document return values and parameters respectively, but from the documentation, nothing is stated about JSON returns.

I could for instance, document the return type as

@return $value string A JSON string that contains the status code and error messages if applicable.

But I hardly consider that proper, especially for returns involving more complex data structures (imagine something similar Twitter's statuses/user_timeline) particularly for the "get" and "view" API methods.

On the other hand, for parameters, I'm not sure if it is correct for me to create one line for each parameter (considering all the parameters are wrapped in one JSON string) like:

@param string $id The ID of the user to be updated.
@param string $first_name optional The first name of the user.
@param string $last_name optional The last name of the user.

I am open to exploring other options if phpDocumentor cannot fulfill this need - just suggest!

Was it helpful?

Solution

I'm not aware of any syntax that can give you additional structural element definition about the JSON strings you have in play here. I can address some basic thoughts though.

Since no explicit arguments are passed to edit(), no @param tags should be used anyway. At best, maybe include a "@uses UserController::$request" with a description that explains how its $data array should find any "arguments for edit() to act on" in $data's ['args'] key. Explaining the needed info about ['args'] and its structure would have to be pure text description. There is no point in having some kind of "structured documentation layout" here... such doc elements only exist to 1) be linked to from other docs, 2) affect doc layout format when displaying the element. I guess I'd approach it like this, in the docblock for edit():

* @uses UserController::$request
*           $request has its own $data array, whose ['args'] key 
*           should contain a JSON value.  In the JSON, keys represent
*           the fields to edit, values are the new values.

As for the return, since there is an actual return here rather than just behind-the-scenes modifications being done, I would use a true @return tag:

* @return string JSON that indicates success/failure of the update,
*                or JSON that indicates an error occurred.

You can certainly expand on this by displaying examples of the JSON strings at each point, but aside from the docs being able to render the JSON like actual JSON rather than just text, I don't see what else you could be after. I'd likely choose to display only the status return JSON examples in the docblock's Long Description, and refer the reader to the docs for the createError() method to see the error JSON layout, rather than trying to cram them all into the tags.

/**
 * edit() method
 *
 * The edit() method examines values already set elsewhere, acts on the edits requested
 * by those values, and returns an indication of whether or not the edits succeeded.
 * 
 * An array key of $data['args'] must be set in the UserController::$request object.
 * It must contain a JSON string that lists the fields to update and the values to use.
 * 
 * Example:
 * <code>
 * {
 *     "id": 1
 *     "first_name": "John"
 *     "last_name": "Doe"
 * }
 * </code>
 *
 * "id" is required, while other fields are optional.
 *
 * The JSON string that is returned by edit() will normally indicate whether or not
 * the edits were performed successfully.
 *
 * Success:
 * <code>
 * {
 *     "status": 1
 * }
 * </code>
 * Failure:
 * <code>
 * {
 *     "status": 0
 * }
 * </code>
 *
 * In the case of validation errors with the values used in the updates,
 * a JSON error string would be returned, in the format generated
 * by the createError() method.
 *
 * @return string JSON that indicates success/failure of the update,
 *                or JSON that indicates an error occurred.
 *
 * @uses UserController::$request
 * @see  UserController::createError()
 */

You may feel like this is a lot to put in there, but you have to understand that you're trying to explain some behind-the-scenes voodoo to the coder/consumer that's reading the doc. Rather than calling the method with direct arguments, you're having to explain how the user must provide arguments in a roundabout way. The verbosity in the long description goes a long way to avoid the user feeling like he's missing something in understanding how to correctly use that edit() method.

OTHER TIPS

I see on this case, your needs is make documentation for your API than documented your code. For API Documentation you can use specific tools for this, not use tools like PHPDocumentor. I use apiary.io for API documentation, and here the sample of mine

http://docs.dollyaswinnet.apiary.io/

There are many tools like this, and commonly they are commercial. I choose apiary.io because it is still free before.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top