emsifa / evo

Evolve your Laravel code

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Create attribute to transform property name like `json` tag in golang.

emsifa opened this issue · comments

It is common to use snake_case in PHP/Laravel project, especially for database column names. In other side, Javascript use camelCase for variable/property name. If we build API without convert naming case, our code will looks inconsistent. But, converting naming case manually need extra work and will add more complexity to our code. In Laravel, we can use Transformer or Resource class to handle response, but how about the request?

That is why we may need an attribute to handle this elegantly.

For example, we can create From (for dto) and To (for response) attributes like following code below:

Request:

class StorePostDto extends Dto
{
    public string $title;
    public string $body;

    #[From('categoryId')]
    public int $category_id;
}

Response:

class StorePostResponse extends JsonResponse
{
    public string $title;
    public string $body;

    #[To('categoryId')]
    public int $category_id;
}

Controller:

public function store(#[Body] StorePostDto $dto): StorePostResponse
{
    $post = Post::create($dto->toArray());
    return StorePostResponse::fromArray($post);
}

Example above, will transform request value below:

{
    "title": "Lorem Ipsum",
    "body": "Lorem ipsum dolor sit amet",
    "categoryId": 12
}

Into PHP StorePostDto object:

$dto->title = "Lorem Ipsum";
$dto->body = "Lorem ipsum dolor sit amet";
$dto->category_id = 12; // <- notice this

That is why, in Post::create method, we don't have to convert categoryId to category_id manually.

Also, for the response, we convert value from Post instance (result of Post::create) below:

$post->id = 1;
$post->title = "Lorem Ipsum";
$post->body = "Lorem ipsum dolor sit amet";
$post->category_id = 12; // <- notice this

Into JSON response:

{
    "id": 1,
    "title": "Lorem Ipsum",
    "body": "Lorem ipsum dolor sit amet",
    "categoryId": 12
}

Then in our JS code, we can still use camelCase consistently, also in PHP we can still use snake_case consistently.