Search code examples
phplaraveleloquentswaggeropenapi

Laravel eloquent models with swagger openApi annotations problem


So in my user model I have a function fullname that returns the full name of the user :


/**
 * @return Attribute
 */
public function fullname(): Attribute
{
    return new Attribute(
        get: fn () => trim($this->firstname . ' ' . $this->lastname),
    );
}

and it works as expected, now i want to add OpenAPI annotations on my model : I did it like so :


class User extends Authenticatable
{
    ...
       
    protected $appends = [
        'fullname'
    ];

    #[OA\Property(type: "string", example: "Jhon")] 
    private $firstname; 

    #[OA\Property(type: "string", example: "Doe")] 
    private $lastname;
    
    /**
     * @return Attribute
     */
    public function fullname(): Attribute
    {
        return new Attribute(
            get: fn () => trim($this->firstname . ' ' . $this->lastname),
        );
    }
}

at this point the function no longer works as intended :

$this->firstname and $this->lastname

no longer return values they are null.

Issue : I want to keep the the annotations but also have the function work.

Note : if you access your user through eloquent ex. ( User::all()->first(); ) we get both the first and last name but we don't get the fullname, thanks for the help


Solution

  • https://github.com/DarkaOnLine/L5-Swagger/issues/157

    according to this issue : defining the properties on the model will generate a lot of problems with eloquent

    I found 3 ways to solve this problem :

    option 1 : the least amount of refactoring you need to do

    keeping the annotations and removing the properties definitions ex : this :

    #[OA\Property(type: "string", example: "Jhon")] 
    private $firstname; 
    
    #[OA\Property(type: "string", example: "Doe")] 
    private $lastname;
    

    will become this :

    #[OA\Property(property: "firstname", type: "string", example: "Jhon")] 
    #[OA\Property(property: "lastname",type: "string", example: "Doe")]
    

    note: the attributes or the annotations must be above a variable or a function or it will generate an error.

    option 2 : cleaner but adds more work

    put your open api declaration somewhere else. ex :

    option 3 : and this is what i used

    add your propreties to your schema declaration example :

    #[OA\Schema(schema: "IUser", properties: [
        new OA\Property(property: "firstname", type: "string", example: "Jhon"),
        new OA\Property(property: "lastname",type: "string", example: "Doe")
    ])]