Skip to content

Commit

Permalink
chore: move native
Browse files Browse the repository at this point in the history
  • Loading branch information
dawkaka committed Jul 10, 2024
1 parent d99f4f2 commit 7cc6a7e
Show file tree
Hide file tree
Showing 2 changed files with 145 additions and 0 deletions.
59 changes: 59 additions & 0 deletions native/native.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package apitoolkitnative

import (
"bytes"
"context"
"io"
"net/http"
"net/http/httptest"
"time"

apt "github.com/apitoolkit/apitoolkit-go"
"github.com/google/uuid"
)

// Middleware collects request, response parameters and publishes the payload
func Middleware(c *apt.Client) func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
msgID := uuid.Must(uuid.NewRandom())
newCtx := context.WithValue(req.Context(), apt.CurrentRequestMessageID, msgID)

errorList := []apt.ATError{}
newCtx = context.WithValue(newCtx, apt.ErrorListCtxKey, &errorList)
newCtx = context.WithValue(newCtx, apt.CurrentClient, c)
req = req.WithContext(newCtx)

reqBuf, _ := io.ReadAll(req.Body)
req.Body.Close()
req.Body = io.NopCloser(bytes.NewBuffer(reqBuf))

rec := httptest.NewRecorder()
start := time.Now()
next.ServeHTTP(rec, req)

recRes := rec.Result()
// io.Copy(res, recRes.Body)
for k, v := range recRes.Header {
for _, vv := range v {
res.Header().Add(k, vv)
}
}
resBody, _ := io.ReadAll(recRes.Body)
res.WriteHeader(recRes.StatusCode)
res.Write(resBody)

config := c.GetConfig()

payload := c.BuildPayload(apt.GoDefaultSDKType, start,
req, recRes.StatusCode,
reqBuf, resBody, recRes.Header, nil, req.URL.Path,
config.RedactHeaders, config.RedactRequestBody, config.RedactResponseBody,
errorList,
msgID,
nil,
)
c.PublishMessage(req.Context(), payload)
})
}
}
86 changes: 86 additions & 0 deletions native/native_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package apitoolkitnative

import (
"context"
"encoding/json"
"io"
"net/http"
"net/http/httptest"
"testing"
"time"

apt "github.com/apitoolkit/apitoolkit-go"
"github.com/imroc/req"
"github.com/stretchr/testify/assert"
)

func TestNativeGoMiddleware(t *testing.T) {
client := &apt.Client{}
client.SetConfig(&apt.Config{
RedactHeaders: []string{"X-Api-Key", "Accept-Encoding"},
RedactResponseBody: apt.ExampleDataRedaction,
})
var publishCalled bool
client.PublishMessage = func(ctx context.Context, payload apt.Payload) error {
assert.Equal(t, "POST", payload.Method)
assert.Equal(t, "/test", payload.URLPath)
assert.Equal(t, map[string]string(nil), payload.PathParams)
assert.Equal(t, map[string][]string{
"param1": {"abc"},
"param2": {"123"},
}, payload.QueryParams)

assert.Equal(t, map[string][]string{
"Accept-Encoding": {"gzip"},
"Content-Length": {"437"},
"Content-Type": {"application/json"},
"User-Agent": {"Go-http-client/1.1"},
"X-Api-Key": {"past-3"},
}, payload.RequestHeaders)
assert.Equal(t, map[string][]string{
"Content-Type": {"application/json"},
"X-Api-Key": {"applicationKey"},
}, payload.ResponseHeaders)
assert.Equal(t, "/test?param1=abc&param2=123", payload.RawURL)
assert.Equal(t, http.StatusAccepted, payload.StatusCode)
assert.Greater(t, payload.Duration, 1000*time.Nanosecond)
assert.Equal(t, apt.GoDefaultSDKType, payload.SdkType)

reqData, _ := json.Marshal(apt.ExampleData2)
respData, _ := json.Marshal(apt.ExampleDataRedacted)

assert.Equal(t, reqData, payload.RequestBody)
assert.Equal(t, respData, payload.ResponseBody)

publishCalled = true
return nil
}

handlerFn := func(w http.ResponseWriter, r *http.Request) {
body, err := io.ReadAll(r.Body)
assert.NoError(t, err)
assert.NotEmpty(t, body)

jsonByte, err := json.Marshal(apt.ExampleData)
assert.NoError(t, err)

w.Header().Add("Content-Type", "application/json")
w.Header().Add("X-API-KEY", "applicationKey")
w.WriteHeader(http.StatusAccepted)
w.Write(jsonByte)
}

ts := httptest.NewServer(client.Middleware(http.HandlerFunc(handlerFn)))
defer ts.Close()

_, err := req.Post(ts.URL+"/test",
req.Param{"param1": "abc", "param2": 123},
req.Header{
"Content-Type": "application/json",
"X-API-KEY": "past-3",
},
req.BodyJSON(apt.ExampleData2),
)
assert.NoError(t, err)
assert.True(t, publishCalled)
}

0 comments on commit 7cc6a7e

Please sign in to comment.