Skip to content

Commit

Permalink
get feeds
Browse files Browse the repository at this point in the history
  • Loading branch information
YukiOnishi1129 committed Dec 12, 2024
1 parent 65990bd commit f0d33ce
Show file tree
Hide file tree
Showing 16 changed files with 1,524 additions and 1,229 deletions.
6 changes: 6 additions & 0 deletions bff/apollo-gateway/src/grpc/content/content_pb.d.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

53 changes: 52 additions & 1 deletion bff/apollo-gateway/src/grpc/content/content_pb.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions bff/apollo-gateway/src/proto/content/content.proto
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ message GetArticleOGPRequest{

message GetFeedsResponse {
repeated FeedEdge feedEdge = 1;
PageInfo page_info = 2;
}

message GetFeedsRequest {
Expand Down
501 changes: 257 additions & 244 deletions micro-service/bookmark-service/grpc/content/content.pb.go

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion micro-service/content-service/cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,20 +86,22 @@ func main() {
// infrastructure layer
// persistence layer
aps := persistence.NewArticlePersistence(db)
fps := persistence.NewFeedPersistence(db)
// external layer
bex := external.NewBookmarkExternal(bClient)
faex := external.NewFavoriteExternal(faClient)

// adapter layer
// persistence adapter
apa := persistenceadapter.NewArticlePersistenceAdapter(aps)
fpa := persistenceadapter.NewFeedPersistenceAdapter(fps)
// external adapter
bea := externaladapter.NewBookmarkExternalAdapter(bex)
faea := externaladapter.NewFavoriteExternalAdapter(faex)

// application layer
// usecase layer
cuc := usecase.NewContentUseCase(apa, bea, faea)
cuc := usecase.NewContentUseCase(apa, fpa, bea, faea)

// interface layer
chd := handler.NewContentHandler(cuc)
Expand Down
501 changes: 257 additions & 244 deletions micro-service/content-service/grpc/content/content.pb.go

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package persistenceadapter

import (
"context"

cpb "github.com/YukiOnishi1129/techpicks/micro-service/content-service/grpc/content"
"github.com/YukiOnishi1129/techpicks/micro-service/content-service/internal/domain/entity"
"github.com/YukiOnishi1129/techpicks/micro-service/content-service/internal/domain/repository"
"github.com/volatiletech/sqlboiler/v4/queries/qm"
)

type FeedPersistenceAdapter interface {
GetFeeds(ctx context.Context, req *cpb.GetFeedsRequest, limit int) (entity.FeedSlice, error)
}

type feedPersistenceAdapter struct {
feedRepository repository.FeedRepository
}

func NewFeedPersistenceAdapter(feedRepository repository.FeedRepository) FeedPersistenceAdapter {
return &feedPersistenceAdapter{
feedRepository: feedRepository,
}
}

func (fpa *feedPersistenceAdapter) GetFeeds(ctx context.Context, req *cpb.GetFeedsRequest, limit int) (entity.FeedSlice, error) {
q := []qm.QueryMod{
// qm.InnerJoin("platforms ON feeds.platform_id = platforms.id"),
// qm.InnerJoin("categories ON feeds.category_id = categories.id"),
qm.Where("feeds.deleted_at IS NULL"),
qm.Load(qm.Rels(entity.FeedRels.Platform)),
qm.Load(qm.Rels(entity.FeedRels.Category)),
qm.OrderBy("feeds.created_at ASC"),
qm.Limit(limit),
}

if req.GetCursor() != "" {
q = append(q, qm.Where("feeds.created_at < (SELECT created_at FROM feeds WHERE id = ?)", req.GetCursor()))
}

if req.GetPlatformSiteType().GetValue() != 0 {
switch {
case req.GetPlatformSiteType().GetValue() == 1:
q = append(q, qm.Where("platforms.site_type = ?", 1))
case req.GetPlatformSiteType().GetValue() == 2:
q = append(q, qm.Where("platforms.site_type = ?", 2))
case req.GetPlatformSiteType().GetValue() == 3:
q = append(q, qm.Where("platforms.site_type = ?", 3))
}
}

if req.GetPlatformId().GetValue() != "" {
q = append(q, qm.Where("platforms.id = ?", req.GetPlatformId().GetValue()))
}

if req.GetKeyword().GetValue() != "" {
q = append(q, qm.Expr(
qm.And("name LIKE ?", "%"+req.GetKeyword().GetValue()+"%"),
qm.Or("description LIKE ?", "%"+req.GetKeyword().GetValue()+"%"),
))
}

feeds, err := fpa.feedRepository.GetFeeds(ctx, q)
if err != nil {
return nil, err
}

return feeds, nil
}
Original file line number Diff line number Diff line change
Expand Up @@ -274,14 +274,16 @@ func Test_UseCase_CreateUploadArticle(t *testing.T) {
}, nil).AnyTimes()

testArticleRepository := persistence.NewArticlePersistence(db)
testFeedRepository := persistence.NewFeedPersistence(db)
testBookmarkExternal := external.NewBookmarkExternal(mockBookmarkClient)
testFavoriteExternal := external.NewFavoriteExternal(mockFavoriteClient)

testArticlePersistenceAdapter := persistenceadapter.NewArticlePersistenceAdapter(testArticleRepository)
testFeedPersistenceAdapter := persistenceadapter.NewFeedPersistenceAdapter(testFeedRepository)
testBookmarkExternalAdapter := externaladapter.NewBookmarkExternalAdapter(testBookmarkExternal)
testFavoriteExternalAdapter := externaladapter.NewFavoriteExternalAdapter(testFavoriteExternal)

testContentUseCase := NewContentUseCase(testArticlePersistenceAdapter, testBookmarkExternalAdapter, testFavoriteExternalAdapter)
testContentUseCase := NewContentUseCase(testArticlePersistenceAdapter, testFeedPersistenceAdapter, testBookmarkExternalAdapter, testFavoriteExternalAdapter)

if tt.recordArticles != nil {
for _, v := range tt.recordArticles {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,25 @@ type ContentUseCase interface {
GetArticles(ctx context.Context, req *cpb.GetArticlesRequest) (*cpb.GetArticlesResponse, error)
CreateUploadArticle(ctx context.Context, req *cpb.CreateUploadArticleRequest) (*cpb.CreateArticleResponse, error)
GetArticleOGP(ctx context.Context, articleURL string) (*cpb.GetArticleOGPResponse, error)

GetFeeds(ctx context.Context, req *cpb.GetFeedsRequest) (*cpb.GetFeedsResponse, error)
}

type contentUseCase struct {
articlePersistenceAdapter persistenceadapter.ArticlePersistenceAdapter
feedPersistenceAdapter persistenceadapter.FeedPersistenceAdapter
bookmarkExternalAdapter externaladapter.BookmarkExternalAdapter
favoriteExternalAdapter externaladapter.FavoriteExternalAdapter
}

func NewContentUseCase(apa persistenceadapter.ArticlePersistenceAdapter, bea externaladapter.BookmarkExternalAdapter, fea externaladapter.FavoriteExternalAdapter) ContentUseCase {
func NewContentUseCase(
apa persistenceadapter.ArticlePersistenceAdapter,
fpa persistenceadapter.FeedPersistenceAdapter,
bea externaladapter.BookmarkExternalAdapter,
fea externaladapter.FavoriteExternalAdapter) ContentUseCase {
return &contentUseCase{
articlePersistenceAdapter: apa,
feedPersistenceAdapter: fpa,
bookmarkExternalAdapter: bea,
favoriteExternalAdapter: fea,
}
Expand Down
46 changes: 46 additions & 0 deletions micro-service/content-service/internal/application/usecase/feed.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,57 @@
package usecase

import (
"context"

cpb "github.com/YukiOnishi1129/techpicks/micro-service/content-service/grpc/content"
"github.com/YukiOnishi1129/techpicks/micro-service/content-service/internal/domain/entity"
"google.golang.org/protobuf/types/known/timestamppb"
"google.golang.org/protobuf/types/known/wrapperspb"
)

func (cu *contentUseCase) GetFeeds(ctx context.Context, req *cpb.GetFeedsRequest) (*cpb.GetFeedsResponse, error) {
limit := 10
if req.GetLimit() > 0 {
limit = int(req.GetLimit())
}

feeds, err := cu.feedPersistenceAdapter.GetFeeds(ctx, req, limit)
if err != nil {
return nil, err
}

edges := make([]*cpb.FeedEdge, len(feeds))

for i, feed := range feeds {
res := cu.convertPBFeed(*feed)
// TODO: fetch my feed data from connecting to my feed service
res.MyFeedIds = []string{}
edges[i] = &cpb.FeedEdge{
Cursor: feed.ID,
Feed: res,
}
}

if len(edges) == 0 {
return &cpb.GetFeedsResponse{
FeedEdge: edges,
PageInfo: &cpb.PageInfo{
HasNextPage: false,
EndCursor: "",
},
}, nil
}

res := &cpb.GetFeedsResponse{
FeedEdge: edges,
PageInfo: &cpb.PageInfo{
HasNextPage: len(edges) == limit,
EndCursor: edges[len(edges)-1].Cursor,
},
}
return res, nil
}

func (cu *contentUseCase) convertPBFeed(f entity.Feed) *cpb.Feed {
feed := &cpb.Feed{
Id: f.ID,
Expand All @@ -27,5 +72,6 @@ func (cu *contentUseCase) convertPBFeed(f entity.Feed) *cpb.Feed {
}
feed.Platform = cu.convertPBPlatform(*f.R.Platform)
feed.Category = cu.convertPBCategory(*f.R.Category)
feed.MyFeedIds = []string{}
return feed
}
12 changes: 12 additions & 0 deletions micro-service/content-service/internal/domain/repository/feed.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package repository

import (
"context"

"github.com/YukiOnishi1129/techpicks/micro-service/content-service/internal/domain/entity"
"github.com/volatiletech/sqlboiler/v4/queries/qm"
)

type FeedRepository interface {
GetFeeds(ctx context.Context, q []qm.QueryMod) (entity.FeedSlice, error)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package persistence

import (
"context"
"database/sql"

"github.com/YukiOnishi1129/techpicks/micro-service/content-service/internal/domain/entity"
"github.com/YukiOnishi1129/techpicks/micro-service/content-service/internal/domain/repository"
"github.com/volatiletech/sqlboiler/v4/queries/qm"
)

type feedPersistence struct {
db *sql.DB
}

func NewFeedPersistence(db *sql.DB) repository.FeedRepository {
return &feedPersistence{
db: db,
}
}

func (fp *feedPersistence) GetFeeds(ctx context.Context, q []qm.QueryMod) (entity.FeedSlice, error) {
// boil.DebugMode = true
feeds, err := entity.Feeds(q...).All(ctx, fp.db)
if err != nil {
if err == sql.ErrNoRows {
return nil, nil
}
return nil, err
}
// boil.DebugMode = false
return feeds, nil
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import (
)

func (ch *contentHandler) GetFeeds(ctx context.Context, req *cpb.GetFeedsRequest) (*cpb.GetFeedsResponse, error) {
// res, err := ch.contentUseCase.GetFeeds(ctx, req)
// if err != nil {
// return nil, err
// }
return nil, nil
res, err := ch.contentUseCase.GetFeeds(ctx, req)
if err != nil {
return nil, err
}
return res, nil
}
Loading

0 comments on commit f0d33ce

Please sign in to comment.