考虑一个允许您创建、列出和查看带有照片的博客文章的应用程序。
但是,该应用程序还提供了一个位置,用户可以在其中查看他们在所有博客文章中添加的所有照片。用户还可以单独更新这些照片的标题。
请注意,我们不希望用户能够自行添加、删除或更新照片。他们只能在博客环境中这样做。
为此,我需要一个列表、更新、创建博客文章(带照片)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)
}
复制
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
层中应该有不同的结构,以避免发送存储库结构。基本上将存储库结构转换为服务结构,并将服务结构转换为存储库结构。
在事务内运行创建方法也是一个好主意。您可以使用依赖注入来注入事务。