how to wrap Laravel resource with swagger

Viewed 324

I am learning how to use laravel with swagger, and I have this issue:

I have the user controller:

UserController.php

class UserController extends Controller
{
    /**
     * Shows authenticated user information
     * 
     * @OA\Get(
     *     tags={"Authorize"},
     *     path="/user",
     *     summary="get user detail",
     *     security={{ "AuthBearer":{} }},
     *     @OA\Response(
     *          response="200", 
     *          description="success",
     *          @OA\JsonContent(
     *              ref="#/components/schemas/UserResource"
     *          )
     *      ),
     *     @OA\Response(response="401", description="Unauthenticated")
     * )
     *     
     * @return \Illuminate\Http\Response
     */  
    public function user()
    {                
        return new UserResource(auth()->user());
    }
}

UserResource.php

/**
 * Class UserResource
 * 
 * @OA\Schema(
 *  @OA\Xml(name="UserResource")
 * )
 */
class UserResource extends JsonResource
{
    /**
     * Transform the resource into an array.
     * 
     * @OA\Property(format="int64", title="ID", default=1, description="ID", property="id"),
     * @OA\Property(format="string", title="name", default="Demo", description="Name", property="name"),
     * @OA\Property(format="string", title="username", default="demo", description="Username", property="username"),
     * @OA\Property(format="string", title="avatar_path", default="https://via.placeholder.com/640x480.png/0000bb?text=avatar", description="Avatar Path", property="avatar_path")
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request)
    {        
        return [
            'id' => $this->id,
            'name' => $this->name,
            'username' => $this->username,
            'avatar_path' => $this->avatar_path            
        ];
    }
}

this is working fine, but in the swagger docs, the example value for this route is this:

{
  "id": 1,
  "name": "demo",
  "username": "demo",
  "avatar_path": "https://via.placeholder.com/640x480.png/0000bb?text=avatar"
}

But when I execute the route in swagger, it returns this:

{
  "data": {
    "id": 1,
    "name": "demo",
    "username": "demo",
    "avatar_path": "https://via.placeholder.com/640x480.png/0000bb?text=avatar"
  }
}

This is wrapped inside a data property, I would like that the example has the same format, how could achieve that? thanks.

1 Answers

You can write in UserResource.php:

/**
 * @OA\Schema(
 *   @OA\Xml(name="UserResource"),
 *   @OA\Property(property="data", type="array",
 *      @OA\Items(ref="#/components/schemas/User"))
 *   ),
 * )
 */

And in model User.php

/**
 * @OA\Schema(
 *   @OA\Xml(name="User"),
 *   @OA\Property(format="int64", title="ID", default=1, description="ID", property="id"),
 *   @OA\Property(format="string", title="name", default="Demo", description="Name", property="name"),
 *   @OA\Property(format="string", title="username", default="demo", description="Username", property="username"),
 *   @OA\Property(format="string", title="avatar_path", default="https://via.placeholder.com/640x480.png/0000bb?text=avatar", description="Avatar Path", property="avatar_path")
 * )
 */
Related