lundi 2 octobre 2023

Mapping Models/DB to an external API, what is recommended design?

What would be the best way to handle mapping laravel models to an external API.

The external API has entities such as:

  • user
  • posts
  • comments

On my local DB I also have similar entities:

  • user
  • posts
  • comments

I need to store certain info in my DB whenever modifying them on the external API, basically mapping the API to the DB.

What is the recommended approach or design pattern for this?

What I have tried:

1- Directly in the model

class User extends Authenticatable
{
    public function posts()
    {
        return $this->hasMany(Post::class);
    }

    public function createPost(array $data, array $attributes)
    {
       $postId = Http::post('.../post', $data)->json('data.postId');

        $this->posts()->create(array_merge([
            'post_id' => $postId,
        ], $attributes));
    }
}

///

$user->createPost([
  'title' => 'foo',
  'content' => 'bar'
], [
  'publish_date' => now()
])

I don't really like calling APIs inside the model, and there are problems with naming conflicts, such as updating a post, what do I call the method in the Post Model, $post->updatePost()?, it does not feel right.

2 -Using a service:


class UserService
{

    public function __construct(
        private User $user
    ) {
    }

    public function createPost(array $data, array $attributes = [])
    {
       $postId = Http::post('.../post', $data)->json('data.postId');

        $this->user->posts()->create(array_merge([
            'post_id' => $postId,
        ], $attributes));
    }
}

///

$userService = new UserService($user);

$userService->createPost([
  'title' => 'foo',
  'content' => 'bar'
], [
  'publish_date' => now()
])

The service approach feels cleaner, but I wonder if there is any other design pattern I could follow for above approach that is better/cleaner.

Has anyone implemented something similar, if yes, how did you do it? And did you call your wrapper class a service, or is it rather a wrapper/adapter/decorater?

Aucun commentaire:

Enregistrer un commentaire