Go语言 带照片的Blog-Post应用程序的存储库模式实现

w8f9ii69  于 2023-09-28  发布在  Go
关注(0)|答案(1)|浏览(61)

考虑一个应用程序,允许您创建,列表和查看带有照片的博客帖子。
然而,该应用程序还提供了一个地方,用户可以查看他们在所有博客文章中添加的所有照片。用户还可以单独更新这些照片的标题。
请注意,我们不希望用户能够自行添加、删除或更新照片。他们只能在博客中这样做。
为此,我需要一个列表,更新,创建博客后(与照片)API。我还需要一个单独的列表和updateCaption API的照片。
我试图理解如何在存储库模式和DDD中适应这一点。
考虑到存储库是按域聚合创建的,我觉得最好的方法是有两个存储库博客和照片。blogpost repository有更新/创建/列出带有照片的博客文章的方法。还有一个photo repository,它只有一个list和updateCaption方法。这是正确的实现吗?
我对这个实现的一个担心是,我将photo作为聚合根,并将其作为blogpost聚合中的实体,它可能不是一个正确的DDD/存储库模式实现。

** Package 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)
}

** Package 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)
}
jhiyze9q

jhiyze9q1#

复制Photo结构/存储库是没有意义的。你有两个不同的仓库。Photo使用ID链接到博客文章。
您可以做的是在存储库包之外处理这种关系。当创建请求进来时,在blogpost存储库中创建帖子,然后在链接到Post ID的photo存储库中创建照片。
要获取帖子的照片,请创建一个方法,返回链接到给定博客帖子的照片:
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层中使用不同的结构,以避免发送存储库结构。基本上是将存储库结构转换为服务结构,将服务结构转换为存储库结构。
在事务内部运行create方法也是一个好主意。您可以使用依赖注入来注入事务。

相关问题