带有照片应用程序的博客文章的存储库模式实现

问题描述 投票:0回答:1

考虑一个允许您创建、列出和查看带有照片的博客文章的应用程序。

但是,该应用程序还提供了一个位置,用户可以在其中查看他们在所有博客文章中添加的所有照片。用户还可以单独更新这些照片的标题。

请注意,我们不希望用户能够自行添加、删除或更新照片。他们只能在博客环境中这样做。

为此,我需要一个列表、更新、创建博客文章(带照片)API。我还需要一个单独的照片列表和 updateCaption API。

我试图了解如何将其融入存储库模式和 DDD。
考虑到存储库是按域聚合创建的,我认为最好的方法是拥有两个存储库博客文章和照片。

blogpost repository
具有更新/创建/列出带有照片的博客文章的方法。另一个
photo repository
只包含一个列表和 updateCaption 方法。这是正确的实现吗?

我对此实现的一个担忧是,我将

photo
作为聚合根并作为
blogpost
聚合中的实体,并且它可能不是正确的 DDD/存储库模式实现。

以包装形式

repository/blogpost/

// in entity.go file
type BlogPost struct {
    ID      string
    Name    string
    Author  string
    Content string
    Photos  []Photo
}

type Photo struct {
    ID      string
    Caption string
    URL     string
}

// repository.go
type repository interface {
    CreateBlogPost(context.Context, BlogPost) (BlogPost, error)
    UpdateBlogPost(context.Context, BlogPost) (BlogPost, error)
    ListBlogPosts(context.Context) ([]BlogPost, error)
}

以包装形式

repository/photo/

// in entity.go file
type Photo struct {
    ID         string
    Caption    string
    BlogPostID int
    URL        string
}

// in repository.go file
type repository interface {
    UpdateCaption(ctx context.Context, ID string, Caption string) (Photo, error)
    ListPhotos(context.Context) ([]Photo, error)
}
go repository-pattern ddd-repositories
1个回答
0
投票

复制

Photo
结构/存储库是没有意义的。您拥有的是两个不同的存储库。
Photo
使用 ID 链接到博客文章。

您可以做的是在存储库包之外处理这种关系。当收到创建请求时,在

blogpost
存储库中创建帖子,然后在链接到
photo
ID 的
Post
存储库中创建照片。

要获取帖子的照片,请创建一个返回链接到给定博客帖子的照片的方法:

photo
存储库:

type repository interface {
    CreatePhoto(context.Context, Photo) (Photo, error)
    UpdateCaption(ctx context.Context, ID string, Caption string) (Photo, error)
    ListPhotos(context.Context) ([]Photo, error)
    PostPhotos(context.Context, postID string) ([]Photo, error)
}

要创建和检索帖子和照片,请考虑包名称

service
作为示例:

service

func CreatePost(post BlogPost, photos []Photo) error {
    p, err := blogpostRepo.CreateBlogPost(context.TODO(), post)
    if err != nil {
        return err
    }
    for _, photo := range photos {
        photo.PostID = p.ID
        _, err := photoRepo.CreatePhoto(context.TODO(), photo)
        if err != nil {
            return err
        }
    }
}

func GetPost(id string) (BlogPost, error) {
    post, err := blogpostRepo.GetPost(id)
    // handle error
    postPhotos, err := photoRepo.PostPhotos(id)
    // handle error
}

您的

service
层中应该有不同的结构,以避免发送存储库结构。基本上将存储库结构转换为服务结构,并将服务结构转换为存储库结构。

在事务内运行创建方法也是一个好主意。您可以使用依赖注入来注入事务。

© www.soinside.com 2019 - 2024. All rights reserved.