Skip to content

Commit

Permalink
feat: init requests base on go
Browse files Browse the repository at this point in the history
  • Loading branch information
fanjindong committed Jan 2, 2020
1 parent afafc51 commit 15df864
Show file tree
Hide file tree
Showing 10 changed files with 521 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,5 @@

# Dependency directories (remove the comment below to include it)
# vendor/

.idea
15 changes: 15 additions & 0 deletions error.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package requests

import "github.com/pkg/errors"

var (
ErrInvalidJson = errors.New("invalid Json value")

// ErrUnrecognizedEncoding will be throwed while changing response encoding
// if encoding is not recognized
ErrUnrecognizedEncoding = errors.New("Unrecognized encoding")

// ErrInvalidMethod will be throwed when method not in
// [HEAD, GET, POST, DELETE, OPTIONS, PUT, PATCH, CONNECT, TRACE]
ErrInvalidMethod = errors.New("Method is invalid")
)
11 changes: 11 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module github.com/fanjindong/go-requests

go 1.12

require (
github.com/ajg/form v1.5.1
github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394
github.com/gin-gonic/gin v1.5.0
github.com/pkg/errors v0.8.1
github.com/stretchr/testify v1.4.0
)
50 changes: 50 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU=
github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY=
github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394 h1:OYA+5W64v3OgClL+IrOD63t4i/RW7RqrAVl9LTZ9UqQ=
github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394/go.mod h1:Q8n74mJTIgjX4RBBcHnJ05h//6/k6foqmgE45jTQtxg=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-gonic/gin v1.5.0 h1:fi+bqFAx/oLK54somfCtEZs9HeH1LHVoEPUgARpTqyc=
github.com/gin-gonic/gin v1.5.0/go.mod h1:Nd6IXA8m5kNZdNEHMBd93KT+mdY3+bewLgRvmCsR2Do=
github.com/go-playground/locales v0.12.1 h1:2FITxuFt/xuCNP1Acdhv62OzaCiviiE4kotfhkmOqEc=
github.com/go-playground/locales v0.12.1/go.mod h1:IUMDtCfWo/w/mtMfIE/IG2K+Ey3ygWanZIBtBW0W2TM=
github.com/go-playground/universal-translator v0.16.0 h1:X++omBR/4cE2MNg91AoC3rmGrCjJ8eAeUP/K/EKx4DM=
github.com/go-playground/universal-translator v0.16.0/go.mod h1:1AnU7NaIRDWWzGEKwgtJRd2xk99HeFyHw3yid4rvQIY=
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/json-iterator/go v1.1.7 h1:KfgG9LzI+pYjr4xvmz/5H4FXjokeP+rlHLhv3iH62Fo=
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/leodido/go-urn v1.1.0 h1:Sm1gr51B1kKyfD2BlRcLSiEkffoG96g6TPv6eRoEiB8=
github.com/leodido/go-urn v1.1.0/go.mod h1:+cyI34gQWZcE1eQU7NVgKkkzdXDQHr1dBMtdAPozLkw=
github.com/mattn/go-isatty v0.0.9 h1:d5US/mDsogSGW37IV293h//ZFaeajb69h+EHFsv2xGg=
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo=
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs=
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a h1:aYOabOQFp6Vj6W1F80affTUvO9UxmJRx8K0gsfABByQ=
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/go-playground/assert.v1 v1.2.1 h1:xoYuJVE7KT85PYWrN730RguIQO0ePzVRfFMXadIrXTM=
gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE=
gopkg.in/go-playground/validator.v9 v9.29.1 h1:SvGtYmN60a5CVKTOzMSyfzWDeZRxRuGvRQyEAKbw1xc=
gopkg.in/go-playground/validator.v9 v9.29.1/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
49 changes: 49 additions & 0 deletions main_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package requests

import (
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin/binding"
"os"
"testing"
)

func getHandler(c *gin.Context) {
c.JSON(200, gin.H{
"url": c.Request.URL.String(),
})
}

func postHandler(c *gin.Context) {
reqJson := make(map[string]interface{})

if p := c.Query("params"); p != "" {
reqJson["params"] = p
}

type form struct {
Data string `form:"form"`
}
f := form{}
_ = c.ShouldBindWith(&f, binding.FormPost)
if f.Data != "" {
reqJson["form"] = f.Data
}

_ = c.ShouldBindJSON(&reqJson)
c.JSON(200, gin.H{
"data": reqJson,
})
}

func TestMain(m *testing.M) {
r := gin.Default()

r.GET("/get", getHandler)
r.POST("/post", postHandler)
r.PUT("/put", postHandler)

go r.Run() // 监听并在 0.0.0.0:8080 上启动服务

code := m.Run()
os.Exit(code)
}
62 changes: 62 additions & 0 deletions option.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package requests

import (
"bytes"
"encoding/json"
"fmt"
"github.com/ajg/form"
"github.com/pkg/errors"
"io/ioutil"
"net/http"
"strings"
)

type Option interface {
ApplyClient(client *http.Client)
ApplyRequest(req *http.Request) error
}

type Params map[string]interface{}

func (p Params) ApplyClient(client *http.Client) {}

func (p Params) ApplyRequest(req *http.Request) error {
var rawQuery []string
if req.URL.RawQuery != "" {
rawQuery = append(rawQuery, req.URL.RawQuery)
}

for key, value := range p {
rawQuery = append(rawQuery, fmt.Sprintf("%s=%s", key, value))
}
req.URL.RawQuery = strings.Join(rawQuery, "&")
return nil
}

type Json map[string]interface{}

func (j Json) ApplyClient(client *http.Client) {}
func (j Json) ApplyRequest(req *http.Request) error {
jsonBytes, err := json.Marshal(j)
if err != nil {
return errors.Wrap(ErrInvalidJson, err.Error())
}
jsonBuffer := bytes.NewBuffer(jsonBytes)
req.Body = ioutil.NopCloser(jsonBuffer)
req.Header.Set("Content-Type", "application/json")
return nil
}

type Data map[string]interface{}

func (d Data) ApplyClient(client *http.Client) {}
func (d Data) ApplyRequest(req *http.Request) error {
data, err := form.EncodeToString(d)
if err != nil {
return errors.Wrap(ErrInvalidJson, err.Error())
}
dataReader := strings.NewReader(data)
req.Body = ioutil.NopCloser(dataReader)
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
return nil
}
52 changes: 52 additions & 0 deletions requests.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package requests

const (
version = "0.0.1"
userAgent = "go-requests/" + version
author = "fanjindong"
)

const (
GET = "GET"
POST = "POST"
PUT = "PUT"
DELETE = "DELETE"
OPTIONS = "OPTIONS"
PATCH = "PATCH"
HEAD = "HEAD"
)

func Get(url string, option ...Option) (*Response, error) {
s := NewSession()
return s.Request(GET, url, option...)
}

func Post(url string, option ...Option) (*Response, error) {
s := NewSession()
return s.Request(POST, url, option...)
}

func Put(url string, option ...Option) (*Response, error) {
s := NewSession()
return s.Request(PUT, url, option...)
}

func Delete(url string, option ...Option) (*Response, error) {
s := NewSession()
return s.Request(DELETE, url, option...)
}

func Options(url string, option ...Option) (*Response, error) {
s := NewSession()
return s.Request(OPTIONS, url, option...)
}

func Patch(url string, option ...Option) (*Response, error) {
s := NewSession()
return s.Request(PATCH, url, option...)
}

func Head(url string, option ...Option) (*Response, error) {
s := NewSession()
return s.Request(HEAD, url, option...)
}
79 changes: 79 additions & 0 deletions requests_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package requests

import (
"github.com/stretchr/testify/assert"
"testing"
)

var BaseUrl = "http://127.0.0.1:8080"

func TestGet(t *testing.T) {
type input struct {
url string
params Params
}

tests := []struct {
input input
want string
}{
{input: input{url: BaseUrl + "/get", params: Params{"a": "1"}}, want: "/get?a=1"},
{input: input{url: BaseUrl + "/get", params: Params{"a": "1", "b": "2"}}, want: "/get?a=1&b=2"},
{input: input{url: BaseUrl + "/get?", params: Params{"a": "1"}}, want: "/get?a=1"},
{input: input{url: BaseUrl + "/get?a=1", params: Params{}}, want: "/get?a=1"},
{input: input{url: BaseUrl + "/get?a=1", params: Params{"b": "2"}}, want: "/get?a=1&b=2"},
}

for _, ts := range tests {
resp, err := Get(ts.input.url, ts.input.params)
assert.NoError(t, err)
respData := make(map[string]interface{})
err = resp.Json(&respData)
assert.NoError(t, err)
got := respData["url"]
assert.Equal(t, ts.want, got)
}
}

func TestPost(t *testing.T) {
url := BaseUrl + "/post"
tests := []struct {
input []Option
want map[string]interface{}
}{
{input: []Option{Json{"a": 1.1}}, want: map[string]interface{}{"a": 1.1}},
{input: []Option{Params{"params": "1"}, Json{"b": 2.2}}, want: map[string]interface{}{"params": "1", "b": 2.2}},
}

for _, ts := range tests {
resp, err := Post(url, ts.input...)
assert.NoError(t, err)
respData := make(map[string]interface{})
err = resp.Json(&respData)
assert.NoError(t, err)
got := respData["data"]
assert.EqualValues(t, ts.want, got)
}
}

func TestPut(t *testing.T) {
url := BaseUrl + "/put"
tests := []struct {
input []Option
want map[string]interface{}
}{
{input: []Option{Json{"a": 1.1}}, want: map[string]interface{}{"a": 1.1}},
{input: []Option{Params{"params": "1"}, Json{"b": 2.2}}, want: map[string]interface{}{"params": "1", "b": 2.2}},
{input: []Option{Params{"params": "1"}, Data{"form": "2.2"}}, want: map[string]interface{}{"params": "1", "form": "2.2"}},
}

for _, ts := range tests {
resp, err := Put(url, ts.input...)
assert.NoError(t, err)
respData := make(map[string]interface{})
err = resp.Json(&respData)
assert.NoError(t, err)
got := respData["data"]
assert.EqualValues(t, ts.want, got)
}
}
Loading

0 comments on commit 15df864

Please sign in to comment.