Skip to content

Commit

Permalink
Merge pull request #4 from Just4Ease/dev
Browse files Browse the repository at this point in the history
feat: used json for parsing, but graphqljson for parsing introspection
  • Loading branch information
Just4Ease committed Sep 4, 2021
2 parents 90127d2 + 98436dc commit 606e98d
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 18 deletions.
3 changes: 1 addition & 2 deletions _labs/clients/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,7 @@ func main() {
gen := generator.NewClientGenerator("./services")

clients := []struct {
serviceName string
opts []generator.ClientGeneratorOption
opts []generator.ClientGeneratorOption
}{
{
opts: []generator.ClientGeneratorOption{
Expand Down
22 changes: 18 additions & 4 deletions client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/Just4Ease/axon/v2"
"github.com/Just4Ease/axon/v2/messages"
"github.com/Just4Ease/axon/v2/options"
"github.com/Yamashou/gqlgenc/graphqljson"
"github.com/pkg/errors"
"github.com/vektah/gqlparser/v2/gqlerror"
"log"
Expand Down Expand Up @@ -179,14 +180,18 @@ func (c *Client) Exec(ctx context.Context, operationName, query string, respData
return fmt.Errorf("request failed: %w", err)
}

return parseResponse(result, 200, respData)
isIntrospection := false
if operationName == "introspect" {
isIntrospection = true
}
return parseResponse(result, 200, respData, isIntrospection)
}

func (c *Client) ServiceName() string {
return c.opts.remoteServiceName
}

func parseResponse(body []byte, httpCode int, result interface{}) error {
func parseResponse(body []byte, httpCode int, result interface{}, isIntrospection bool) error {
errResponse := &ErrorResponse{}
isKOCode := httpCode < 200 || 299 < httpCode
if isKOCode {
Expand All @@ -197,7 +202,7 @@ func parseResponse(body []byte, httpCode int, result interface{}) error {
}

// some servers return a graphql error with a non OK http code, try anyway to parse the body
if err := unmarshal(body, result); err != nil {
if err := unmarshal(body, result, isIntrospection); err != nil {
if gqlErr, ok := err.(*GqlErrorList); ok {
errResponse.GqlErrors = &gqlErr.Errors
} else if !isKOCode { // if is KO code there is already the http error, this error should not be returned
Expand All @@ -218,7 +223,7 @@ type response struct {
Errors json.RawMessage `json:"errors"`
}

func unmarshal(data []byte, res interface{}) error {
func unmarshal(data []byte, res interface{}, isIntrospection bool) error {
resp := response{}
if err := json.Unmarshal(data, &resp); err != nil {
return fmt.Errorf("failed to decode data %s: %w", string(data), err)
Expand All @@ -234,6 +239,15 @@ func unmarshal(data []byte, res interface{}) error {
return errors
}

if !isIntrospection {
if err := graphqljson.UnmarshalData(resp.Data, res); err != nil {
return fmt.Errorf("failed to decode data into response %s: %w", string(data), err)
}

return nil

}

if err := json.Unmarshal(resp.Data, res); err != nil {
return fmt.Errorf("failed to decode data into response %s: %w", string(data), err)
}
Expand Down
24 changes: 12 additions & 12 deletions client/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func TestUnmarshal(t *testing.T) {
var path ast.Path
_ = json.Unmarshal([]byte(`["query GetUser","viewer","repositories","nsodes"]`), &path)
r := &fakeRes{}
err := unmarshal([]byte(qqlSingleErr), r)
err := unmarshal([]byte(qqlSingleErr), r, true)
expectedErr := &GqlErrorList{
Errors: gqlerror.List{{
Message: "Field 'nsodes' doesn't exist on type 'RepositoryConnection'",
Expand Down Expand Up @@ -60,7 +60,7 @@ func TestUnmarshal(t *testing.T) {
var path3 ast.Path
_ = json.Unmarshal([]byte(`["fragment LanguageFragment"]`), &path3)
r := &fakeRes{}
err := unmarshal([]byte(gqlMultipleErr), r)
err := unmarshal([]byte(gqlMultipleErr), r, true)
expectedErr := &GqlErrorList{
Errors: gqlerror.List{
{
Expand Down Expand Up @@ -110,7 +110,7 @@ func TestUnmarshal(t *testing.T) {
var path ast.Path
_ = json.Unmarshal([]byte(`["query GetUser","viewer","repositories","nsodes"]`), &path)
r := &fakeRes{}
err := unmarshal([]byte(gqlDataAndErr), r)
err := unmarshal([]byte(gqlDataAndErr), r, true)
expectedErr := &GqlErrorList{
Errors: gqlerror.List{{
Message: "Field 'nsodes' doesn't exist on type 'RepositoryConnection'",
Expand All @@ -132,14 +132,14 @@ func TestUnmarshal(t *testing.T) {
t.Run("invalid json", func(t *testing.T) {
t.Parallel()
r := &fakeRes{}
err := unmarshal([]byte(invalidJSON), r)
err := unmarshal([]byte(invalidJSON), r, true)
require.EqualError(t, err, "failed to decode data invalid: invalid character 'i' looking for beginning of value")
})

t.Run("valid data", func(t *testing.T) {
t.Parallel()
r := &fakeRes{}
err := unmarshal([]byte(validData), r)
err := unmarshal([]byte(validData), r, true)
require.NoError(t, err)

expected := &fakeRes{
Expand All @@ -151,14 +151,14 @@ func TestUnmarshal(t *testing.T) {
t.Run("bad data format", func(t *testing.T) {
t.Parallel()
r := &fakeRes{}
err := unmarshal([]byte(withBadDataFormat), r)
err := unmarshal([]byte(withBadDataFormat), r, true)
require.EqualError(t, err, "failed to decode data into response {\"data\": \"notAndObject\"}: : : : : json: cannot unmarshal string into Go value of type client.fakeRes")
})

t.Run("bad data format", func(t *testing.T) {
t.Parallel()
r := &fakeRes{}
err := unmarshal([]byte(withBadErrorsFormat), r)
err := unmarshal([]byte(withBadErrorsFormat), r, true)
require.EqualError(t, err, "faild to parse graphql errors. Response content {\"errors\": \"bad\"} - json: cannot unmarshal string into Go struct field GqlErrorList.errors of type gqlerror.List ")
})
}
Expand All @@ -168,7 +168,7 @@ func TestParseResponse(t *testing.T) {
t.Run("single error", func(t *testing.T) {
t.Parallel()
r := &fakeRes{}
err := parseResponse([]byte(qqlSingleErr), 200, r)
err := parseResponse([]byte(qqlSingleErr), 200, r, true)

expectedType := &ErrorResponse{}
require.IsType(t, expectedType, err)
Expand All @@ -182,7 +182,7 @@ func TestParseResponse(t *testing.T) {
t.Run("bad error format", func(t *testing.T) {
t.Parallel()
r := &fakeRes{}
err := parseResponse([]byte(withBadErrorsFormat), 200, r)
err := parseResponse([]byte(withBadErrorsFormat), 200, r, true)

expectedType := fmt.Errorf("%w", errors.New("some"))
require.IsType(t, expectedType, err)
Expand All @@ -191,7 +191,7 @@ func TestParseResponse(t *testing.T) {
t.Run("network error with valid gql error response", func(t *testing.T) {
t.Parallel()
r := &fakeRes{}
err := parseResponse([]byte(qqlSingleErr), 400, r)
err := parseResponse([]byte(qqlSingleErr), 400, r, true)

expectedType := &ErrorResponse{}
require.IsType(t, expectedType, err)
Expand All @@ -206,7 +206,7 @@ func TestParseResponse(t *testing.T) {
t.Run("network error with not valid gql error response", func(t *testing.T) {
t.Parallel()
r := &fakeRes{}
err := parseResponse([]byte(invalidJSON), 500, r)
err := parseResponse([]byte(invalidJSON), 500, r, true)

expectedType := &ErrorResponse{}
require.IsType(t, expectedType, err)
Expand All @@ -220,7 +220,7 @@ func TestParseResponse(t *testing.T) {
t.Run("no error", func(t *testing.T) {
t.Parallel()
r := &fakeRes{}
err := parseResponse([]byte(validData), 200, r)
err := parseResponse([]byte(validData), 200, r, true)

require.Nil(t, err)
})
Expand Down
1 change: 1 addition & 0 deletions generator/client_generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,7 @@ func generateClientCode(ctx context.Context, g *ClientGenerator, option ...api.O
}

if err := config.LoadSchema(ctx, g.cfg, g.Conn, client.SetRemoteServiceName(g.RemoteServiceName)); err != nil {
fmt.Print(err, " skem \n")
return fmt.Errorf("failed to load schema: %w", err)
}

Expand Down

0 comments on commit 606e98d

Please sign in to comment.