Remove intermediate interface and provide Set methods for HttpClient and Token.

- Make the "Client" struct construction-friendly so it can be easily initialized with "new(footballdata.Client)".
- Rewrite example_test.go to show the respective new usage. Make it clear here that the SetToken call is optional.

This would fix #2.
api/rm-interface
Icedream 2016-06-26 12:57:14 +02:00
parent 1d952c49e9
commit e6526da3e0
13 changed files with 54 additions and 50 deletions

View File

@ -6,7 +6,7 @@ import (
) )
type request struct { type request struct {
fdClient *client fdClient *Client
path string path string
urlValues url.Values urlValues url.Values
} }

View File

@ -10,56 +10,50 @@ import (
"net/url" "net/url"
) )
/*
Provides a high-level client to talk to the API that football-data.org offers.
To create an instance please use NewClient(h).
*/
type Client interface {
Fixture(id uint64) FixtureRequest
Fixtures() FixturesRequest
SoccerSeason(id uint64) SoccerSeasonRequest
FixturesOfSoccerSeason(soccerSeasonId uint64) SoccerSeasonFixturesRequest
LeagueTableOfSoccerSeason(soccerSeasonId uint64) SoccerSeasonLeagueTableRequest
TeamsOfSoccerSeason(soccerSeasonId uint64) SoccerSeasonTeamsRequest
SoccerSeasons() SoccerSeasonsRequest
Team(id uint64) TeamRequest
FixturesOfTeam(id uint64) TeamFixturesRequest
SetToken(authToken string)
}
/* /*
Provides a high-level client implementation to talk to the API that football-data.org offers. Provides a high-level client implementation to talk to the API that football-data.org offers.
To create an instance please use NewClient(h). A new instance of Client will by default use the default HTTP client and no
authentication token. To configure this, Client provides methods to set the
token and the HTTP client. For more information, see the respective documentation
of SetHttpClient and SetToken.
*/ */
type client struct { type Client struct {
httpClient *http.Client httpClient http.Client
// Insert an API token here if you have one. It will be sent across with all requests. // Insert an API token here if you have one. It will be sent across with all requests.
AuthToken string authToken string
} }
// NewClient creates a new Client instance that wraps around the given HTTP client. // NewClient creates a new Client instance that wraps around the given HTTP client.
// //
// Call SetToken to add your token. // A call to this method is not necessary in order to create a working instance
func NewClient(h *http.Client) Client { // of Client. `new(footballdata.Client)` works just as fine.
return &client{httpClient: h} func NewClient(h *http.Client) *Client {
return &Client{httpClient: *h}
} }
// SetToken sets the authentication token. // SetToken sets the authentication token.
// Calling this method is *optional*. // Calling this method is *optional*.
func (c *client) SetToken(authToken string) { func (c *Client) SetToken(authToken string) {
c.AuthToken = authToken c.authToken = authToken
} }
func (c *client) req(path string, pathValues ...interface{}) request { // SetHttpClient sets the client that should be used to send out requests.
// Calling this method is *optional*.
func (c *Client) SetHttpClient(client *http.Client) {
if client == nil {
panic("client must not be nil")
}
c.httpClient = *client
}
func (c *Client) req(path string, pathValues ...interface{}) request {
return request{c, fmt.Sprintf(path, pathValues...), url.Values{}} return request{c, fmt.Sprintf(path, pathValues...), url.Values{}}
} }
// Executes an HTTP request with given parameters and on success returns the response wrapped in a JSON decoder. // Executes an HTTP request with given parameters and on success returns the response wrapped in a JSON decoder.
func (c *client) doJson(method string, path string, values url.Values) (j *json.Decoder, meta ResponseMeta, err error) { func (c *Client) doJson(method string, path string, values url.Values) (j *json.Decoder, meta ResponseMeta, err error) {
// Create request // Create request
req := &http.Request{ req := &http.Request{
Method: method, Method: method,
@ -68,8 +62,8 @@ func (c *client) doJson(method string, path string, values url.Values) (j *json.
} }
// Set request headers // Set request headers
if len(c.AuthToken) > 0 { if len(c.authToken) > 0 {
req.Header.Set("X-Auth-Token", c.AuthToken) req.Header.Set("X-Auth-Token", c.authToken)
} }
req.Header.Set("X-Response-Control", "minified") req.Header.Set("X-Response-Control", "minified")
req.Header.Set("User-Agent", "go-footballdata/0.0") req.Header.Set("User-Agent", "go-footballdata/0.0")

View File

@ -8,10 +8,10 @@ import (
) )
func Example() { func Example() {
// Create client // Create client and tell it to use our API token
client := footballdata.NewClient(http.DefaultClient) client := new(footballdata.Client)
// Tell it to use our API token // Tell it to use our API token (optional)
client.SetToken("<insert your api token here>") client.SetToken("<insert your api token here>")
// Get list of seasons... // Get list of seasons...
@ -30,7 +30,11 @@ func ExampleClient() {
// Create client // Create client
client := footballdata.NewClient(http.DefaultClient) client := footballdata.NewClient(http.DefaultClient)
/* Do something with the client instance... */ // Tell it to use our API token (optional)
client.SetToken("<insert your api token here>")
// Do something with the client instance...
// Here we just fetch the listed soccer seasons on the API
seasons, err := client.SoccerSeasons().Do() seasons, err := client.SoccerSeasons().Do()
if err != nil { if err != nil {
panic(err) panic(err)
@ -40,10 +44,16 @@ func ExampleClient() {
} }
} }
func ExampleClient_withToken() { func ExampleClient_setTokenAndHttpClient() {
// Create client // Create client
client := footballdata.NewClient(http.DefaultClient) client := new(footballdata.Client)
// Tell it to use our API token // If you have an API token, you can tell the Client instance to use it
client.SetToken("<insert your api token here>") client.SetToken("<insert your api token here>")
// The Client instance also allows you to use your own HTTP client configuration
client.SetHttpClient(&http.Client{
Transport: &http.Transport{
DisableCompression: true,
}})
} }

View File

@ -22,6 +22,6 @@ func (r FixtureRequest) Do() (s Fixture, err error) {
} }
// Fixture prepares a request to fetch the fixtures of a soccer season. // Fixture prepares a request to fetch the fixtures of a soccer season.
func (c *client) Fixture(id uint64) FixtureRequest { func (c *Client) Fixture(id uint64) FixtureRequest {
return FixtureRequest{c.req("fixture/%d", id)} return FixtureRequest{c.req("fixture/%d", id)}
} }

View File

@ -31,6 +31,6 @@ func (r FixturesRequest) Do() (s FixturesResponse, err error) {
} }
// Fixtures prepares a request to fetch the fixtures of a soccer season. // Fixtures prepares a request to fetch the fixtures of a soccer season.
func (c *client) Fixtures() FixturesRequest { func (c *Client) Fixtures() FixturesRequest {
return FixturesRequest{c.req("fixtures")} return FixturesRequest{c.req("fixtures")}
} }

View File

@ -14,6 +14,6 @@ func (r SoccerSeasonRequest) Do() (s SoccerSeason, err error) {
} }
// SoccerSeason prepares a request to fetch the complete list of soccer seasons. // SoccerSeason prepares a request to fetch the complete list of soccer seasons.
func (c *client) SoccerSeason(id uint64) SoccerSeasonRequest { func (c *Client) SoccerSeason(id uint64) SoccerSeasonRequest {
return SoccerSeasonRequest{c.req("soccerseasons/%d", id)} return SoccerSeasonRequest{c.req("soccerseasons/%d", id)}
} }

View File

@ -31,6 +31,6 @@ func (r SoccerSeasonFixturesRequest) Do() (s FixtureList, err error) {
} }
// FixturesOfSoccerSeason prepares a request to fetch the fixtures of a soccer season. // FixturesOfSoccerSeason prepares a request to fetch the fixtures of a soccer season.
func (c *client) FixturesOfSoccerSeason(soccerSeasonId uint64) SoccerSeasonFixturesRequest { func (c *Client) FixturesOfSoccerSeason(soccerSeasonId uint64) SoccerSeasonFixturesRequest {
return SoccerSeasonFixturesRequest{c.req("soccerseasons/%d/fixtures", soccerSeasonId)} return SoccerSeasonFixturesRequest{c.req("soccerseasons/%d/fixtures", soccerSeasonId)}
} }

View File

@ -22,6 +22,6 @@ func (r SoccerSeasonLeagueTableRequest) Do() (s SoccerSeason, err error) {
} }
// LeagueTableOfSoccerSeason prepares a new request to fetch the league table of a given soccer season. // LeagueTableOfSoccerSeason prepares a new request to fetch the league table of a given soccer season.
func (c *client) LeagueTableOfSoccerSeason(soccerSeasonId uint64) SoccerSeasonLeagueTableRequest { func (c *Client) LeagueTableOfSoccerSeason(soccerSeasonId uint64) SoccerSeasonLeagueTableRequest {
return SoccerSeasonLeagueTableRequest{c.req("soccerseasons/%d/leagueTable", soccerSeasonId)} return SoccerSeasonLeagueTableRequest{c.req("soccerseasons/%d/leagueTable", soccerSeasonId)}
} }

View File

@ -14,6 +14,6 @@ func (r SoccerSeasonTeamsRequest) Do() (s TeamList, err error) {
} }
// TeamsOfSoccerSeason prepares a new request to fetch the league table of a given soccer season. // TeamsOfSoccerSeason prepares a new request to fetch the league table of a given soccer season.
func (c *client) TeamsOfSoccerSeason(soccerSeasonId uint64) SoccerSeasonTeamsRequest { func (c *Client) TeamsOfSoccerSeason(soccerSeasonId uint64) SoccerSeasonTeamsRequest {
return SoccerSeasonTeamsRequest{c.req("soccerseasons/%d/leagueTable", soccerSeasonId)} return SoccerSeasonTeamsRequest{c.req("soccerseasons/%d/leagueTable", soccerSeasonId)}
} }

View File

@ -22,6 +22,6 @@ func (r SoccerSeasonsRequest) Do() (s SoccerSeasonList, err error) {
} }
// SoccerSeasons prepares a request to fetch the complete list of soccer seasons. // SoccerSeasons prepares a request to fetch the complete list of soccer seasons.
func (c *client) SoccerSeasons() SoccerSeasonsRequest { func (c *Client) SoccerSeasons() SoccerSeasonsRequest {
return SoccerSeasonsRequest{c.req("soccerseasons")} return SoccerSeasonsRequest{c.req("soccerseasons")}
} }

View File

@ -21,6 +21,6 @@ func (r TeamRequest) Do() (s Team, err error) {
} }
// Team prepares a request to fetch a team's information. // Team prepares a request to fetch a team's information.
func (c *client) Team(id uint64) TeamRequest { func (c *Client) Team(id uint64) TeamRequest {
return TeamRequest{c.req("teams/%d", id), id} return TeamRequest{c.req("teams/%d", id), id}
} }

View File

@ -37,6 +37,6 @@ func (r TeamFixturesRequest) Do() (s FixturesResponse, err error) {
} }
// FixturesOfTeam prepares a request to fetch the fixtures of a soccer season. // FixturesOfTeam prepares a request to fetch the fixtures of a soccer season.
func (c *client) FixturesOfTeam(id uint64) TeamFixturesRequest { func (c *Client) FixturesOfTeam(id uint64) TeamFixturesRequest {
return TeamFixturesRequest{c.req("teams/%d/fixtures", id)} return TeamFixturesRequest{c.req("teams/%d/fixtures", id)}
} }

View File

@ -14,6 +14,6 @@ func (r TeamPlayersRequest) Do() (s PlayerList, err error) {
} }
// PlayersOfTeam prepares a request to fetch a team's players. // PlayersOfTeam prepares a request to fetch a team's players.
func (c *client) PlayersOfTeam(id uint64) TeamPlayersRequest { func (c *Client) PlayersOfTeam(id uint64) TeamPlayersRequest {
return TeamPlayersRequest{c.req("teams/%d/players", id)} return TeamPlayersRequest{c.req("teams/%d/players", id)}
} }