diff --git a/frontend/ghost/client.go b/frontend/ghost/client.go index 5f26742..6a286a8 100644 --- a/frontend/ghost/client.go +++ b/frontend/ghost/client.go @@ -2,6 +2,7 @@ package ghost import ( "fmt" + "strconv" "sync" "time" @@ -45,7 +46,7 @@ func (g *HTTPClient) setupClient() { } // doQuery does the method and unmarshals the result into the easyjson Unmarshaler -func (g *HTTPClient) doQuery(method string, v easyjson.Unmarshaler, params ...QueryParam) (err error) { +func (g *HTTPClient) doQuery(method string, v easyjson.Unmarshaler, params Params) (err error) { g.setupClientOnce.Do(g.setupClient) @@ -57,9 +58,7 @@ func (g *HTTPClient) doQuery(method string, v easyjson.Unmarshaler, params ...Qu }() g.setupRequest(method, req) - for _, param := range params { - param.Apply(&req.Header, uri.QueryArgs()) - } + g.applyParams(params, req) err = g.client.DoTimeout(req, res, g.QueryTimeout) if err != nil { @@ -103,13 +102,32 @@ func (g *HTTPClient) setupRequest(path string, req *fasthttp.Request) { } } +// applyParams function additionally configure the http request using params +func (g *HTTPClient) applyParams(p Params, req *fasthttp.Request) (err error) { + + uri := req.URI() + + limit := p.Limit + if limit > 0 { + uri.QueryArgs().Add("limit", strconv.Itoa(limit)) + } + + page := p.Page + if page > 1 { + uri.QueryArgs().Add("page", strconv.Itoa(page)) + } + + return +} + // GetPageBySlug returns the only one page using slug filter func (g *HTTPClient) GetPageBySlug(slug string) (pages *Pages, err error) { pages = &Pages{} + defaultParams := Params{} method := fmt.Sprintf(ghostAPIGetPageBySlug, slug) - err = g.doQuery(method, pages) + err = g.doQuery(method, pages, defaultParams) if err != nil { pages = nil } @@ -118,10 +136,13 @@ func (g *HTTPClient) GetPageBySlug(slug string) (pages *Pages, err error) { } // GetPosts returns posts -func (g *HTTPClient) GetPosts(params ...QueryParam) (posts *Posts, err error) { +func (g *HTTPClient) GetPosts(queryModifiers ...Modifier) (posts *Posts, err error) { posts = &Posts{} - err = g.doQuery(ghostAPIGetPosts, posts, params...) + defaultParams := Params{} + combinedParams := Modifiers(queryModifiers).Apply(defaultParams) + + err = g.doQuery(ghostAPIGetPosts, posts, combinedParams) if err != nil { posts = nil } @@ -130,12 +151,14 @@ func (g *HTTPClient) GetPosts(params ...QueryParam) (posts *Posts, err error) { } // GetPostBySlug returns the only one post using slug filter -func (g *HTTPClient) GetPostBySlug(slug string, params ...QueryParam) (posts *Posts, err error) { +func (g *HTTPClient) GetPostBySlug(slug string, queryModifiers ...Modifier) (posts *Posts, err error) { posts = &Posts{} + defaultParams := Params{} + combinedParams := Modifiers(queryModifiers).Apply(defaultParams) method := fmt.Sprintf(ghostAPIGetPostBySlug, slug) - err = g.doQuery(method, posts, params...) + err = g.doQuery(method, posts, combinedParams) if err != nil { posts = nil } diff --git a/frontend/ghost/ghost.go b/frontend/ghost/ghost.go index a8cb003..fb59855 100644 --- a/frontend/ghost/ghost.go +++ b/frontend/ghost/ghost.go @@ -4,7 +4,7 @@ package ghost // Client is the ghost backend client type Client interface { - GetPosts(params ...QueryParam) (posts *Posts, err error) - GetPostBySlug(slug string, params ...QueryParam) (posts *Posts, err error) - GetPageBySlug(slug string) (pages *Pages, err error) + GetPosts(queryParams ...Modifier) (posts *Posts, err error) + GetPostBySlug(slug string, queryParams ...Modifier) (posts *Posts, err error) + GetPageBySlug(slug string, queryParams ...Modifier) (pages *Pages, err error) } diff --git a/frontend/ghost/params.go b/frontend/ghost/params.go index 4da0076..672ec90 100644 --- a/frontend/ghost/params.go +++ b/frontend/ghost/params.go @@ -1,48 +1,39 @@ package ghost -import ( - "strconv" - - "github.com/valyala/fasthttp" -) - -// QueryParam is the generic query param applier -type QueryParam interface { - Apply(headers *fasthttp.RequestHeader, args *fasthttp.Args) +// Params are generics query argument +type Params struct { + Limit int + Page int } -// QueryLimit returns limit param query -func QueryLimit(limit int) queryLimit { - return queryLimit{limit: limit} -} - -// QueryPage returns page param query -func QueryPage(page int) queryPage { - return queryPage{page: page} -} +// Modifier function takes params and makes some changes +type Modifier func(params Params) Params -// queryLimit implements the limit param query applier -type queryLimit struct{ limit int } +// Modifiers is a list of modifier +type Modifiers []Modifier -// Apply applies the limit argument to the query -func (ql queryLimit) Apply(headers *fasthttp.RequestHeader, args *fasthttp.Args) { +// Apply function modifies params +func (ms Modifiers) Apply(params Params) Params { - if ql.limit == 0 { - return + for _, m := range ms { + params = m(params) } - args.Add("limit", strconv.Itoa(ql.limit)) + return params } -// queryPage implements the page param query applier -type queryPage struct{ page int } - -// Apply applies the page argument to the query -func (qp queryPage) Apply(headers *fasthttp.RequestHeader, args *fasthttp.Args) { - - if qp.page < 2 { - return +// WithLimit modifier setups the limit +func WithLimit(limit int) Modifier { + return func(params Params) Params { + params.Limit = limit + return params } +} - args.Add("page", strconv.Itoa(qp.page)) +// WithPage modifier setups the page +func WithPage(page int) Modifier { + return func(params Params) Params { + params.Page = page + return params + } }