Skip to content

Commit

Permalink
Merge pull request #4 from barthr/refactoring-newsapi-v2
Browse files Browse the repository at this point in the history
Refactoring newsapi v2
  • Loading branch information
barthr committed Oct 3, 2018
2 parents 10f2f8e + f09692c commit e3c36e0
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 43 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ import (
func main() {
c := newsapi.NewClient("<API KEY>", newsapi.WithHTTPClient(http.DefaultClient))

sources, _, err := c.GetSources(context.Background(), &newsapi.SourceParameters{
sources, err := c.GetSources(context.Background(), &newsapi.SourceParameters{
Country: "gb",
})

Expand Down Expand Up @@ -95,7 +95,7 @@ import (
func main() {
c := newsapi.NewClient("<API KEY>", newsapi.WithHTTPClient(http.DefaultClient))

articles, _, err := c.GetTopHeadlines(context.Background(), &newsapi.ArticleParameters{
articles, err := c.GetTopHeadlines(context.Background(), &newsapi.TopHeadlineParameters{
Sources: []string{ "cnn", "time" },
})

Expand Down Expand Up @@ -125,7 +125,7 @@ import (
func main() {
c := newsapi.NewClient("<API KEY>", newsapi.WithHTTPClient(http.DefaultClient))

articles, _, err := c.GetEverything(context.Background(), &newsapi.ArticleParameters{
articles, err := c.GetEverything(context.Background(), &newsapi.EverythingParameters{
Sources: []string{ "cnn", "time" },
})

Expand Down
75 changes: 44 additions & 31 deletions article.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,34 @@ package newsapi
import (
"context"
"errors"
"fmt"
"net/http"
"time"
)

// ArticleParameters are the parameters used for the newsapi article endpoint
// Source must always contain a value
// See http://beta.newsapi.org/docs for more information on the required parameters
type ArticleParameters struct {
Sources []string `url:"sources,omitempty,comma"`
Domains []string `url:"domains,omitempty,comma"`
// TopHeadlineParameters are the parameters which can be used to tweak to request for the top headlines.
type TopHeadlineParameters struct {
Country string `url:"country,omitempty"`
Category string `url:"category,omitempty"`
Sources []string `url:"sources,omitempty,comma"`
Keywords string `url:"q,omitempty"`
Page int `url:"page,omitempty"`
PageSize int `url:"pageSize,omitempty"`
}

// EverythingParameters are the parameters used for the newsapi everything endpoint.
type EverythingParameters struct {
Keywords string `url:"q,omitempty"`
Sources []string `url:"sources,omitempty,comma"`
Domains []string `url:"domains,omitempty,comma"`
ExcludeDomains []string `url:"excludeDomains,omitempty"`

From time.Time `url:"from,omitempty"`
To time.Time `url:"to,omitempty"`

Keywords string `url:"q,omitempty"`
Category string `url:"category,omitempty"`
Language string `url:"language,omitempty"`
SortBy string `url:"sortBy,omitempty"`
Page int `url:"page,omitempty"`

Page int `url:"page,omitempty"`
PageSize int `url:"pageSize,omitempty"`
}

// Article is a single article from the newsapi article response
Expand All @@ -32,66 +43,68 @@ type Article struct {
URL string `json:"url"`
URLToImage string `json:"urlToImage"`
PublishedAt time.Time `json:"publishedAt"`
Content string `json:"content"`
}

// ArticleResponse is the response from the newsapi article endpoint
// Code and Message property will be filled when an error happened
// See http://beta.newsapi.org/docs for more details on the property's
// ArticleResponse is the response from the newsapi article endpoint.
// Code and Message property will be filled when an error happened.
// See http://beta.newsapi.org/docs for more details on the property's.
type ArticleResponse struct {
Status string `json:"status"`
TotalResults int `json:"totalResults"`
Code string `json:"code,omitempty"`
Message string `json:"message,omitempty"`
Articles []Article `json:"articles"`
}

// GetTopHeadlines returns the articles from newsapi
// See http://beta.newsapi.org/docs for more information
// See http://newsapi.org/docs for more information
// It will return the error from newsapi if there is an error
func (c *Client) GetTopHeadlines(ctx context.Context, params *ArticleParameters) (*ArticleResponse, *http.Response, error) {
func (c *Client) GetTopHeadlines(ctx context.Context, params *TopHeadlineParameters) (*ArticleResponse, error) {
return c.getArticles(ctx, "top-headlines", params)
}

// GetEverything returns the articles from newsapi
// See http://beta.newsapi.org/docs for more information
// See http://newsapi.org/docs for more information
// It will return the error from newsapi if there is an error
func (c *Client) GetEverything(ctx context.Context, params *ArticleParameters) (*ArticleResponse, *http.Response, error) {
func (c *Client) GetEverything(ctx context.Context, params *EverythingParameters) (*ArticleResponse, error) {
return c.getArticles(ctx, "everything", params)
}

// GetArticles returns the articles from newsapi
// See http://beta.newsapi.org/docs for more information
// See http://newsapi.org/docs for more information
// It will return the error from newsapi if there is an error
func (c *Client) getArticles(ctx context.Context, u string, params *ArticleParameters) (*ArticleResponse, *http.Response, error) {
func (c *Client) getArticles(ctx context.Context, u string, params interface{}) (*ArticleResponse, error) {
if params == nil {
return nil, nil, errors.New("empty parameters not possible when asking for articles")
return nil, errors.New("empty parameters not possible when asking for articles")
}

if params != nil {
var err error
u, err = setOptions(u, params)

if err != nil {
return nil, nil, err
return nil, err
}
}

req, err := c.newGetRequest(u)
if err != nil {
return nil, nil, err
return nil, err
}

var response *ArticleResponse
var response = struct {
*Error
*ArticleResponse
}{}

resp, err := c.do(ctx, req, &response)
_, err = c.do(ctx, req, &response)

if err != nil {
return nil, nil, err
return nil, err
}

if response.Code != "" {
return nil, nil, fmt.Errorf("[%s] %s", response.Code, response.Message)
if response.Error != nil {
return nil, response.Error
}

return response, resp, nil
return response.ArticleResponse, nil
}
19 changes: 19 additions & 0 deletions error.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package newsapi

import "fmt"

// Error defines an API error from newsapi.
type Error struct {
Code string `json:"code,omitempty"`
Message string `json:"message,omitempty"`
}

func (e Error) Error() string {
return fmt.Sprintf("[%s] %s", e.Code, e.Message)
}

// APIError returns if the given err is of type `newsapi.Error`.
func APIError(err error) bool {
_, ok := err.(*Error)
return ok
}
23 changes: 14 additions & 9 deletions sources.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package newsapi

import (
"context"
"net/http"
)

// SourceParameters are the parameters which can be used in the source request to newsapi
Expand Down Expand Up @@ -35,30 +34,36 @@ type SourceResponse struct {
}

// GetSources returns the sources from newsapi see http://beta.newsapi.org/docs for more information on the parameters
func (c *Client) GetSources(ctx context.Context, params *SourceParameters) (*SourceResponse, *http.Response, error) {
func (c *Client) GetSources(ctx context.Context, params *SourceParameters) (*SourceResponse, error) {
u := "sources"

if params != nil {
var err error
u, err = setOptions(u, params)

if err != nil {
return nil, nil, err
return nil, err
}
}

req, err := c.newGetRequest(u)
if err != nil {
return nil, nil, err
return nil, err
}

var response *SourceResponse

resp, err := c.do(ctx, req, &response)
var response = struct {
*Error
*SourceResponse
}{}

_, err = c.do(ctx, req, &response)
if err != nil {
return nil, nil, err
return nil, err
}

if response.Error != nil {
return nil, response.Error
}

return response, resp, nil
return response.SourceResponse, nil
}

0 comments on commit e3c36e0

Please sign in to comment.