1

I'm using zircote/swagger-php for annotations to generate swagger for my php WebApi.
I have my generic model HttpResponse, it has 2 common properties (messages and statusCode) but data is generic and has different type for every endpoint.

I'm trying to annote it via zircote/swagger-php and use different model for this data property for every endpoint. Can anyone tell me how I can do this?

Right now I'm trying something like below, but its giving me first of those anyOf to every request instead allow me specific which one i want.

/**
 * @OA\Schema()
 */
class HttpResponse
{
    /**
     * @OA\Property(anyOf={
     *          @OA\Schema(ref="#/components/schemas/HolidayRequestSpecificInput"),
     *          @OA\Schema(ref="#/components/schemas/AvailableHolidayDatesApiModel")
     *       })
     */
    public $data;
    /**
     * @OA\Property(type="array", @OA\Items(ref="#/components/schemas/Message"))
     */
    public $messages;
    /**
     * @OA\Property(ref="#/components/schemas/HttpResponseType")
     */
    public $statusCode;

    public function __construct($statusCode = HttpResponseType::Ok, $data = null)
    {
        $this->data = $data;
        $this->messages = [];
        $this->statusCode = $statusCode;
    }

    public function addMessages($messages)
    {
        foreach ($messages as $msg)
            array_push($this->messages, $msg);
    }
}

2 Answers 2

1

Might be that you should use oneOf rather than anyOf.

However, this way things are set up right now each endpoint would return HttpResponse with a choice of data structures which is not ideal.

Better, IMHO, would be to have each endpoint define exactly the data that it returns (unless I am misunderstanding your code).

In that case I'd suggest you split the response schema into a base and explicit @OA\Response definitions for each endpoint.

The downside might be that the annotations do not reflect exactly your code. However, the spec would reflect more explicit the data structures returned by the endpoints.

/**
 * @OA\Schema()
 */
class BaseResponse
{
    /**
     * @OA\Property(type="array", @OA\Items(ref="#/components/schemas/Message"))
     */
    public $messages;

    /**
     * @OA\Property(ref="#/components/schemas/HttpResponseType")
     */
    public $statusCode;
}

/**
 * @OA\Schema()
 */
class HolidayRequestSpecificInput{
    /**
     * @OA\Property()
     */
    public $location;

}

/**
 * @OA\Get(path="/holiday",
 *     @OA\Response(
 *         response="200",
 *         description="OK",
 *         @OA\JsonContent(
 *             allOf={
 *                 @OA\Schema(ref="#/components/schemas/BaseResponse"),
 *                 @OA\Schema(
 *                     @OA\Property(property="data", ref="#/components/schemas/HolidayRequestSpecificInput")
 *                 )
 *             }
 *         )
 *     )
 * )
 */
class Controller{}

Sign up to request clarification or add additional context in comments.

1 Comment

Tbh i don't like duplicate code if not needed, but right now I don't see any better solution that you just wrote.
0

maybe you should use a discriminator as described here : https://swagger.io/docs/specification/data-models/inheritance-and-polymorphism/

Comments

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.