Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add common http methods to client #1

Merged
merged 1 commit into from
Jan 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,26 @@ func main() {
}
```

Common *http verbs(HEAD, OPTIONS, GET, HEAD, POST, PATCH, DELETE)* are also supported
```go
package main

import (
"github.com/davesavic/clink"
"encoding/json"
)

func main() {
client := clink.NewClient()
resp, err := client.Get("https://httpbin.org/get")
// ....
payload, err := json.Marshal(map[string]string{"username": "yumi"})
resp, err := client.Post("https://httpbin.org/post", payload)
}
```

### Examples
For more examples, see the [examples](https://github.com/davesavic/clink/tree/master/examples) directory.

### Contributing
Contributions to Clink are welcome! If you find a bug, have a feature request, or want to contribute code, please open an issue or submit a pull request.
Contributions to Clink are welcome! If you find a bug, have a feature request, or want to contribute code, please open an issue or submit a pull request.
59 changes: 58 additions & 1 deletion client.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ import (
"encoding/base64"
"encoding/json"
"fmt"
"golang.org/x/time/rate"
"io"
"net/http"
"time"

"golang.org/x/time/rate"
)

type Client struct {
Expand Down Expand Up @@ -69,6 +70,62 @@ func (c *Client) Do(req *http.Request) (*http.Response, error) {
return resp, nil
}

func (c *Client) Head(url string) (*http.Response, error) {
req, err := http.NewRequest(http.MethodHead, url, nil)
if err != nil {
return nil, err
}
return c.Do(req)
}

func (c *Client) Options(url string) (*http.Response, error) {
req, err := http.NewRequest(http.MethodOptions, url, nil)
if err != nil {
return nil, err
}
return c.Do(req)
}

func (c *Client) Get(url string) (*http.Response, error) {
req, err := http.NewRequest(http.MethodGet, url, nil)
if err != nil {
return nil, err
}
return c.Do(req)
}

func (c *Client) Post(url string, body io.Reader) (*http.Response, error) {
req, err := http.NewRequest(http.MethodPost, url, body)
if err != nil {
return nil, err
}
return c.Do(req)
}

func (c *Client) Put(url string, body io.Reader) (*http.Response, error) {
req, err := http.NewRequest(http.MethodPut, url, body)
if err != nil {
return nil, err
}
return c.Do(req)
}

func (c *Client) Patch(url string, body io.Reader) (*http.Response, error) {
req, err := http.NewRequest(http.MethodPatch, url, body)
if err != nil {
return nil, err
}
return c.Do(req)
}

func (c *Client) Delete(url string) (*http.Response, error) {
req, err := http.NewRequest(http.MethodDelete, url, nil)
if err != nil {
return nil, err
}
return c.Do(req)
}

type Option func(*Client)

// WithClient sets the http client for the client.
Expand Down
100 changes: 99 additions & 1 deletion client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@ package clink_test
import (
"encoding/base64"
"encoding/json"
"github.com/davesavic/clink"
"io"
"net/http"
"net/http/httptest"
"strings"
"testing"
"time"

"github.com/davesavic/clink"
)

func TestNewClient(t *testing.T) {
Expand Down Expand Up @@ -252,6 +253,103 @@ func TestClient_Do(t *testing.T) {
}
}

func TestClient_Methods(t *testing.T) {
serverFunc := func() *httptest.Server {
return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Add("X-Method", r.Method)
}))
}
resultFunc := func(r *http.Response, m string) bool {
return r.Header.Get("X-Method") == m
}
testCases := []struct {
name string
method string
body io.Reader
setupServer func() *httptest.Server
resultFunc func(*http.Response, string) bool
}{
{
name: "successful head response",
method: http.MethodHead,
setupServer: serverFunc,
resultFunc: resultFunc,
},
{
name: "successful options response",
method: http.MethodOptions,
setupServer: serverFunc,
resultFunc: resultFunc,
},
{
name: "successful get response",
method: http.MethodGet,
setupServer: serverFunc,
resultFunc: resultFunc,
},
{
name: "successful post response",
method: http.MethodPost,
setupServer: serverFunc,
resultFunc: resultFunc,
},
{
name: "successful put response",
method: http.MethodPut,
setupServer: serverFunc,
resultFunc: resultFunc,
},
{
name: "successful patch response",
method: http.MethodPatch,
setupServer: serverFunc,
resultFunc: resultFunc,
},
{
name: "successful delete response",
method: http.MethodDelete,
setupServer: serverFunc,
resultFunc: resultFunc,
},
}

call := func(c *clink.Client, method, url string, body io.Reader) (*http.Response, error) {
switch method {
case http.MethodHead:
return c.Head(url)
case http.MethodOptions:
return c.Options(url)
case http.MethodGet:
return c.Get(url)
case http.MethodPost:
return c.Post(url, body)
case http.MethodPut:
return c.Put(url, body)
case http.MethodPatch:
return c.Patch(url, body)
case http.MethodDelete:
return c.Delete(url)
}
return nil, nil
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
server := tc.setupServer()
defer server.Close()
c := clink.NewClient(clink.WithClient(server.Client()))
if c == nil {
t.Error("expected client to be created")
}
resp, _ := call(c, tc.method, server.URL, tc.body)
if !tc.resultFunc(resp, tc.method) {
t.Errorf("expected result to be successful")
}

})
}
}

func TestClient_ResponseToJson(t *testing.T) {
testCases := []struct {
name string
Expand Down