Skip to content

Instantly share code, notes, and snippets.

@aliuygur
Created August 2, 2022 09:45
Show Gist options
  • Save aliuygur/c25fdfa3deed31dc600259b74fdb03a2 to your computer and use it in GitHub Desktop.
Save aliuygur/c25fdfa3deed31dc600259b74fdb03a2 to your computer and use it in GitHub Desktop.
// client.go
package rickandmorty
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)
// APIError represents an 4xx error from the API.
type APIError struct {
Err string `json:"error"`
}
func (e *APIError) Error() string {
return e.Err
}
func NewClient(baseURL string) *Client {
return &Client{
client: &http.Client{},
baseURL: baseURL,
}
}
type Client struct {
client *http.Client
baseURL string
}
type Character struct {
ID int `json:"id"`
Name string `json:"name"`
Status string `json:"status"`
Species string `json:"species"`
Type string `json:"type"`
Gender string `json:"gender"`
Image string `json:"image"`
URL string `json:"url"`
Created string `json:"created"`
}
// GetCharacter returns a character by ID.
func (c *Client) GetCharacter(id int) (*Character, error) {
req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("%s/character/%d", c.baseURL, id), nil)
if err != nil {
return nil, fmt.Errorf("error creating request: %w", err)
}
req.Header.Set("Accept", "application/json")
req.Header.Set("Content-Type", "application/json")
var character Character
if err := c.makeRequest(req, &character); err != nil {
return nil, err
}
return &character, nil
}
// makeRequest makes a request to the API and unmarshals the response into the given interface.
func (c *Client) makeRequest(r *http.Request, v interface{}) error {
resp, err := c.client.Do(r)
if err != nil {
return err
}
defer resp.Body.Close()
data, err := ioutil.ReadAll(resp.Body)
if err != nil {
return fmt.Errorf("error reading response body: %w", err)
}
switch status := resp.StatusCode; {
case status >= 200 && status < 300: // 2xx
if err := json.Unmarshal(data, v); err != nil {
return fmt.Errorf("error unmarshalling response: %w", err)
}
return nil
case status >= 400 && status < 500: // 4xx
var apiError APIError
if err := json.Unmarshal(data, &apiError); err != nil {
return fmt.Errorf("error unmarshalling response: %w", err)
}
return &apiError
default: // 5xx
return fmt.Errorf("error response: %s", string(data))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment