Skip to content

Commit

Permalink
feat: add Go modules and Go 1.19 compatibility
Browse files Browse the repository at this point in the history
  • Loading branch information
zwartho committed Aug 3, 2023
1 parent 0bdc741 commit 5024604
Show file tree
Hide file tree
Showing 12 changed files with 578 additions and 24 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
timeout-minutes: 20
strategy:
matrix:
go: [ '1.14', '1.15', '1.16', '1.17' ]
go: [ '1.14', '1.15', '1.16', '1.17', '1.18', '1.19' ]
steps:
- name: Checkout rest
uses: actions/checkout@v2
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,4 @@ _testmain.go
.settings.json

temp.go
.vscode
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ This library supports the following Go implementations:
* Go 1.15
* Go 1.16
* Go 1.17
* Go 1.18
* Go 1.19

## Install Package

Expand Down
41 changes: 22 additions & 19 deletions docker/example.go
Original file line number Diff line number Diff line change
@@ -1,24 +1,27 @@
package main

import "github.com/sendgrid/rest"
import "fmt"
import (
"fmt"

"github.com/sendgrid/rest"
)

func main() {
const host = "https://httpbin.org"
param := "get"
endpoint := "/" + param
baseURL := host + endpoint
method := rest.Get
request := rest.Request{
Method: method,
BaseURL: baseURL,
}
response, err := rest.Send(request)
if err != nil {
fmt.Println(err)
} else {
fmt.Println(response.StatusCode)
fmt.Println(response.Body)
fmt.Println(response.Headers)
}
const host = "https://httpbin.org"
param := "get"
endpoint := "/" + param
baseURL := host + endpoint
method := rest.Get
request := rest.Request{
Method: method,
BaseURL: baseURL,
}
response, err := rest.Send(request)
if err != nil {
fmt.Println(err)
} else {
fmt.Println(response.StatusCode)
fmt.Println(response.Body)
fmt.Println(response.Headers)
}
}
5 changes: 5 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module github.com/sendgrid/rest

go 1.14

require golang.org/x/net v0.0.0-20220708220712-1185a9018129
7 changes: 7 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
golang.org/x/net v0.0.0-20220708220712-1185a9018129 h1:vucSRfWwTsoXro7P+3Cjlr6flUMtzCwzlvkxEQtHHB0=
golang.org/x/net v0.0.0-20220708220712-1185a9018129/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
4 changes: 2 additions & 2 deletions rest.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ package rest
import (
"bytes"
"context"
"io/ioutil"
"io"
"net/http"
"net/url"
)
Expand Down Expand Up @@ -97,7 +97,7 @@ func MakeRequest(req *http.Request) (*http.Response, error) {

// BuildResponse builds the response struct.
func BuildResponse(res *http.Response) (*Response, error) {
body, err := ioutil.ReadAll(res.Body)
body, err := io.ReadAll(res.Body)
response := Response{
StatusCode: res.StatusCode,
Body: string(body),
Expand Down
3 changes: 1 addition & 2 deletions rest_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package rest
import (
"errors"
"fmt"
"io/ioutil"
"net/http"
"net/http/httptest"
"net/http/httputil"
Expand Down Expand Up @@ -324,7 +323,7 @@ func TestRepoFiles(t *testing.T) {

func TestLicenseYear(t *testing.T) {
t.Parallel()
dat, err := ioutil.ReadFile("LICENSE")
dat, err := os.ReadFile("LICENSE")

currentYear := time.Now().Year()
r := fmt.Sprintf("%d", currentYear)
Expand Down
5 changes: 5 additions & 0 deletions v2/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module github.com/sendgrid/rest/v2

go 1.14

require golang.org/x/net v0.0.0-20220708220712-1185a9018129
7 changes: 7 additions & 0 deletions v2/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
golang.org/x/net v0.0.0-20220708220712-1185a9018129 h1:vucSRfWwTsoXro7P+3Cjlr6flUMtzCwzlvkxEQtHHB0=
golang.org/x/net v0.0.0-20220708220712-1185a9018129/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
161 changes: 161 additions & 0 deletions v2/rest.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
// Package rest allows for quick and easy access any REST or REST-like API.
package rest

import (
"bytes"
"context"
"io"
"net/http"
"net/url"
)

// Version represents the current version of the rest library
const Version = "2.6.9"

// Method contains the supported HTTP verbs.
type Method string

// Supported HTTP verbs.
const (
Get Method = "GET"
Post Method = "POST"
Put Method = "PUT"
Patch Method = "PATCH"
Delete Method = "DELETE"
)

// Request holds the request to an API Call.
type Request struct {
Method Method
BaseURL string // e.g. https://api.sendgrid.com
Headers map[string]string
QueryParams map[string]string
Body []byte
}

// RestError is a struct for an error handling.
type RestError struct {
Response *Response
}

// Error is the implementation of the error interface.
func (e *RestError) Error() string {
return e.Response.Body
}

// DefaultClient is used if no custom HTTP client is defined
var DefaultClient = &Client{HTTPClient: &http.Client{}}

// Client allows modification of client headers, redirect policy
// and other settings
// See https://golang.org/pkg/net/http
type Client struct {
HTTPClient *http.Client
}

// Response holds the response from an API call.
type Response struct {
StatusCode int // e.g. 200
Body string // e.g. {"result: success"}
Headers map[string][]string // e.g. map[X-Ratelimit-Limit:[600]]
}

// AddQueryParameters adds query parameters to the URL.
func AddQueryParameters(baseURL string, queryParams map[string]string) string {
baseURL += "?"
params := url.Values{}
for key, value := range queryParams {
params.Add(key, value)
}
return baseURL + params.Encode()
}

// BuildRequestObject creates the HTTP request object.
func BuildRequestObject(request Request) (*http.Request, error) {
// Add any query parameters to the URL.
if len(request.QueryParams) != 0 {
request.BaseURL = AddQueryParameters(request.BaseURL, request.QueryParams)
}
req, err := http.NewRequest(string(request.Method), request.BaseURL, bytes.NewBuffer(request.Body))
if err != nil {
return req, err
}
for key, value := range request.Headers {
req.Header.Set(key, value)
}
_, exists := req.Header["Content-Type"]
if len(request.Body) > 0 && !exists {
req.Header.Set("Content-Type", "application/json")
}
return req, err
}

// MakeRequest makes the API call.
func MakeRequest(req *http.Request) (*http.Response, error) {
return DefaultClient.HTTPClient.Do(req)
}

// BuildResponse builds the response struct.
func BuildResponse(res *http.Response) (*Response, error) {
body, err := io.ReadAll(res.Body)
response := Response{
StatusCode: res.StatusCode,
Body: string(body),
Headers: res.Header,
}
res.Body.Close() // nolint
return &response, err
}

// Deprecated: API supports old implementation
func API(request Request) (*Response, error) {
return Send(request)
}

// Send uses the DefaultClient to send your request
func Send(request Request) (*Response, error) {
return SendWithContext(context.Background(), request)
}

// SendWithContext uses the DefaultClient to send your request with the provided context.
func SendWithContext(ctx context.Context, request Request) (*Response, error) {
return DefaultClient.SendWithContext(ctx, request)
}

// The following functions enable the ability to define a
// custom HTTP Client

// MakeRequest makes the API call.
func (c *Client) MakeRequest(req *http.Request) (*http.Response, error) {
return c.HTTPClient.Do(req)
}

// Deprecated: API supports old implementation
func (c *Client) API(request Request) (*Response, error) {
return c.Send(request)
}

// Send will build your request, make the request, and build your response.
func (c *Client) Send(request Request) (*Response, error) {
return c.SendWithContext(context.Background(), request)
}

// SendWithContext will build your request passing in the provided context, make the request, and build your response.
func (c *Client) SendWithContext(ctx context.Context, request Request) (*Response, error) {
// Build the HTTP request object.
req, err := BuildRequestObject(request)
if err != nil {
return nil, err
}
// Pass in the user provided context
req = req.WithContext(ctx)

// Build the HTTP client and make the request.
res, err := c.MakeRequest(req)
if err != nil {
return nil, err
}

// Build Response object.
return BuildResponse(res)
}
Loading

0 comments on commit 5024604

Please sign in to comment.