Coder Social home page Coder Social logo

client-go's Introduction

Grafeas - Go Client Library

Grafeas is an artifact metadata API. This is a client library in Go that utilizes the Grafeas API.

Generating the Library

The Grafeas client libraries are generated using the standard Swagger (aka OpenAPI) specification. The API is defined once in a JSON file, which is then used to auto-generate libraries for all supported languages at once. This simplifies maintainance and upgrades.

Along with the auto-generated portions of the library, there may be manual changes to the library files. These files are preserved between library generations through the .swagger-codegen-ignore file. Therefore, it is expected that new versions of the library are generated on top of previous ones, to preserve the manual changes.

Regenerating the Library

To generate a new version of the library, run the following command:

go generate

This command will download the latest OpenAPI spec file from the main Grafeas repo, download the necessary version of swagger-codegen, and generate the library using the appropriate configuration options.

Upgrading client library version

The config.go.json sets auto-generation options. When upgrading the client version, make sure to update packageVersion field before running the go generate command. All available options can be found by running:

java -jar swagger-codegen-cli.jar config.go.json -l go

Introducing a breaking change

When introducing a breaking change v2, follow Semantic Import Versioning https://research.swtch.com/vgo-import and append the /v2 to the module path.

client-go's People

Contributors

aethanol avatar aysylu avatar daniel-sanche avatar dependabot[bot] avatar emirot avatar lizrice avatar r2wend2 avatar vtsao avatar wkozlik avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

client-go's Issues

StatusCode check in api_grafeas_v1_beta1.go

Problem

Nested if statement that checks for StatusCode == 200 is always ignored:

if localVarHttpResponse.StatusCode < 300 {
	// If we succeed, return the data, otherwise pass on to decode error.
	err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"));
	if err == nil { 
		return localVarReturnValue, localVarHttpResponse, err
	}
}

if localVarHttpResponse.StatusCode >= 300 {
	newErr := GenericSwaggerError{
		body: localVarBody,
		error: localVarHttpResponse.Status,
	}
	//the issue is here
	if localVarHttpResponse.StatusCode == 200 {
		var v V1beta1BatchCreateNotesResponse
		err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type"));
			if err != nil {
				newErr.error = err.Error()
				return localVarReturnValue, localVarHttpResponse, newErr
			}
			newErr.model = v
			return localVarReturnValue, localVarHttpResponse, newErr
	}
	
	return localVarReturnValue, localVarHttpResponse, newErr
}

This code checks if the StatusCode value is more than 300, and, if it is true, it checks if the StatusCode is equal to 200, which means that this nested if statement will never be true.

I did not observe any issues happening because of this problem because if StatusCode == 200 the if statement above (if localVarHttpResponse.StatusCode < 300 ) will be executed.

This problem reoccurs for every function in api_grafeas_v1_beta1.go that expects a response.

Potential Solution

Move StatusCode == 200 if statement inside of if localVarHttpResponse.StatusCode < 300 {} or before it, e.g.:

if localVarHttpResponse.StatusCode < 300 {
	// If we succeed, return the data, otherwise pass on to decode error.
	err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type"));
	if localVarHttpResponse.StatusCode == 200 {
		if err != nil {
			newErr.error = err.Error()
			return localVarReturnValue, localVarHttpResponse, newErr
		}
		newErr.model = localVarReturnValue
		return localVarReturnValue, localVarHttpResponse, newErr
	}
	
	if err == nil { 
		return localVarReturnValue, localVarHttpResponse, err
	}
}

if localVarHttpResponse.StatusCode >= 300 {
	newErr := GenericSwaggerError{
		body: localVarBody,
		error: localVarHttpResponse.Status,
	}
	
	return localVarReturnValue, localVarHttpResponse, newErr
}

Proto/Swagger HTTP JSON to RPC mapping

Problem

The current HTTP JSON to RPC mapping does not seem to generate proper string replacement logic, so the HTTP request will always result in a 404.

Example

The following would yield a 404

grafeasCfg := &grafeasAPI.Configuration{
	BasePath:      "http://localhost:8080",
	DefaultHeader: make(map[string]string),
	UserAgent:     "Swagger-Codegen/0.1.0/go",
}
grafeasClient := grafeasAPI.NewAPIClient(grafeasCfg)
projectID := "projects/myproject"
notesResp, _, err := grafeasClient.GrafeasV1Beta1Api.ListNotes(context.Background(), projectID, nil)
if err != nil {
	log.Fatal(err)
} else {
	log.Print(notesResp.Notes)
}

While a curl against that same project would yield a 200

$ curl http://localhost:8080/v1beta1/projects/myproject/notes
{"notes":[],"nextPageToken":""}

Proto generated client

The following shows the broken string replacement logic

// create path and map variables
localVarPath := a.client.cfg.BasePath + "/v1beta1/{parent=projects/*}/notes"
localVarPath = strings.Replace(localVarPath, "{"+"parent"+"}", fmt.Sprintf("%v", parent), -1)

Reference to code

Derived from:
https://github.com/grafeas/grafeas/blob/6a8d995912a9f10f732e8ffcffbae8830507ed17/proto/v1beta1/grafeas.proto#L121

Simulated

parent := "projects/myproject"
localVarPath := "http://localhost:8080" + "/v1beta1/{parent=projects/*}/notes"
fmt.Println("[CURRENT]  BEFORE REPLACEMENT:", localVarPath)
localVarPath = strings.Replace(localVarPath, "{"+"parent"+"}", fmt.Sprintf("%v", parent), -1)
fmt.Println("[CURRENT]  AFTER REPLACEMENT :", localVarPath)
localVarPath = "http://localhost:8080" + "/v1beta1/{parent}/notes"
fmt.Println("[PROPOSED] BEFORE REPLACEMENT:", localVarPath)
localVarPath = strings.Replace(localVarPath, "{"+"parent"+"}", fmt.Sprintf("%v", parent), -1)
fmt.Println("[PROPOSED] AFTER REPLACEMENT :", localVarPath)
// [CURRENT]  BEFORE REPLACEMENT: http://localhost:8080/v1beta1/{parent=projects/*}/notes
// [CURRENT]  AFTER REPLACEMENT : http://localhost:8080/v1beta1/{parent=projects/*}/notes
// [PROPOSED] BEFORE REPLACEMENT: http://localhost:8080/v1beta1/{parent}/notes
// [PROPOSED] AFTER REPLACEMENT : http://localhost:8080/v1beta1/projects/myproject/notes

Solution

I haven't had time to test yet but changing

rpc ListNotes(ListNotesRequest) returns (ListNotesResponse) {
    option (google.api.http) = {
      get: "/v1beta1/{parent=projects/*}/notes"
    };
  };

to

rpc ListNotes(ListNotesRequest) returns (ListNotesResponse) {
    option (google.api.http) = {
      get: "/v1beta1/{parent}/notes"
    };
  };

should work

JSON difference in the key format between the client and the server

Problem

Server and client json renderers do not match. Client code (defined in client-go) expects json keys in snake_case, and the server code (defined in grafeas/grafeas) sends json keys in camelCase. Thus, server response values are ignored by the client marshaller.

Example

Field definitions:
client-go:
ShortDescription string 'json:"short_description,omitempty"'
grafeas:
ShortDescription string 'protobuf:"bytes,2,opt,name=short_description,json=shortDescription,proto3" json:"short_description,omitempty"'

What the client receives before the values are unmarshalled:
"name":"projects/grafeasclienttest/notes/grafeasattestation","shortDescription":"short","longDescription":"long","kind":"ATTESTATION","relatedUrl":[],"expirationTime":"0001-01-01T00:00:00Z","createTime":"2019-11-12T14:12:44.705616Z","updateTime":"2019-11-12T14:12:44.705616Z","relatedNoteNames":[],"attestationAuthority":{"hint":{"humanReadableName":"projects/grafeasclienttest/notes/grafeasattestation"}}

The final unmarshalled object:
Name:projects/grafeasclienttest/notes/grafeasattestation ShortDescription: LongDescription: Kind:0xc00041b0e0 RelatedUrl:[] ExpirationTime:0001-01-01 00:00:00 +0000 UTC CreateTime:0001-01-01 00:00:00 +0000 UTC UpdateTime:0001-01-01 00:00:00 +0000 UTC RelatedNoteNames:[] Vulnerability:<nil><HIGHLIGHT:END>

Potential Solution

Rename json keys in client-go models to use the camelCase, e.g. (from model_v1beta1_note.go):

// A one sentence description of this note.
ShortDescription string `json:"shortDescription,omitempty"`

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.