Use the Lattice SDK for gRPC in Go
This page shows you how to set up the Lattice SDK for gRPC in Go and make a request.
Click to go to the gRPC SDK repository. By downloading and/or using, you agree to the terms of use. If you do not agree, do not use the SDK.
Install the SDK
To install the SDK:
-
Start a new Go project.
-
Initialize a new Go module with your specific module path.
go mod init <your-module-path>
-
Fetch the Go gRPC SDK and make it available to your integration:
go get github.com/anduril/lattice-sdk-go
-
Make any additional dependencies available in your integration. For the following example, you would need:
go get google.golang.org/grpc
go get google.golang.org/grpc/credentials
Connect to Lattice APIs
Establish a gRPC channel to connect to Lattice APIs:
-
Implement the PerRPCCredentials interface that takes a bearer token:
package main
import (
"context"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
)
// BearerTokenAuth supplies PerRPCCredentials from a given token.
type BearerTokenAuth struct {
Token string
}
// GetRequestMetadata gets the current request metadata, adding the bearer token.
func (b *BearerTokenAuth) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error) {
return map[string]string{
"authorization": "Bearer " + b.Token,
}, nil
}
// RequireTransportSecurity indicates whether the credentials requires transport security.
func (b *BearerTokenAuth) RequireTransportSecurity() bool {
return true // or false if you are developing/testing without TLS
} -
Create the Entities API client instance with the authenticated gRPC channel. Replace $YOUR_BEARER_TOKEN with the token that you previously generated.
package main
import (
"log"
entitymanagerv1 "github.com/anduril/lattice-sdk-go/src/anduril/entitymanager/v1"
)
// ...PerRPCCredentials interface
func main() {
bearerToken := "$YOUR_BEARER_TOKEN" // Replace $YOUR_BEARER_TOKEN with your token. You must keep the word, Bearer, in the metadata string.
opts := []grpc.DialOption{
grpc.WithTransportCredentials(credentials.NewClientTLSFromCert(nil, "")),
grpc.WithPerRPCCredentials(&BearerTokenAuth{Token: bearerToken}),
}
conn, err := grpc.NewClient("$YOUR_LATTICE_URL:443", opts...)
if err != nil {
log.Fatalf("did not connect: %v", err)
}
defer conn.Close()
em := entitymanagerv1.NewEntityManagerAPIClient(conn)
}
Allowing self-signed certificates
Make sure you understand the implications of using self-signed certificates. This should only be used for testing.
In order to connect to a server that is using a self-signed certificate, please update the sample code above to not require transport security.
- grpc.WithTransportCredentials(credentials.NewClientTLSFromCert(nil, "")),
+ grpc.WithTransportCredentials(credentials.NewTLS(
&tls.Config{
InsecureSkipVerify: true,
})),
Example request
The following example combines the code snippets from above and makes a GetEntity
request to the Entities API to fetch an entity from the Common Operational Picture
package main
import (
"context"
"log"
entitymanagerv1 "github.com/anduril/lattice-sdk-go/src/anduril/entitymanager/v1"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
)
// BearerTokenAuth supplies PerRPCCredentials from a given token.
type BearerTokenAuth struct {
Token string
}
// GetRequestMetadata gets the current request metadata, adding the bearer token.
func (b *BearerTokenAuth) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error) {
return map[string]string{
"authorization": "Bearer " + b.Token,
}, nil
}
// RequireTransportSecurity indicates whether the credentials requires transport security.
func (b *BearerTokenAuth) RequireTransportSecurity() bool {
return true // or false if you are developing/testing without TLS
}
func main() {
bearerToken := "$YOUR_BEARER_TOKEN" // Replace $YOUR_BEARER_TOKEN with your token. You must keep the word, Bearer, in the metadata string.
opts := []grpc.DialOption{
grpc.WithTransportCredentials(credentials.NewClientTLSFromCert(nil, "")),
grpc.WithPerRPCCredentials(&BearerTokenAuth{Token: bearerToken}),
}
conn, err := grpc.NewClient("$YOUR_LATTICE_URL:443", opts...)
if err != nil {
log.Fatalf("did not connect: %v", err)
}
defer conn.Close()
em := entitymanagerv1.NewEntityManagerAPIClient(conn)
ctx := context.Background()
request := &entitymanagerv1.GetEntityRequest{
EntityId: "$ENTITY_ID", // Replace $ENTITY_ID with the ID of the entity you published previously.
}
response, err := em.GetEntity(ctx, request)
if err != nil {
log.Fatalf("Error fetching entity: %v", err)
}
log.Printf("Response: %v", response)
}
Clean up your go.mod
file and construct the vendor
directory to store all your dependencies
go mod tidy
go mod vendor
Build and run the example
go build
go run .
If the request is successful and you replaced the entity ID then you should see the entity object you created when setting up your development environment. If you did not change the entity ID to a valid, existing entity, then you will get the following error:
ConnectError: [not_found] entity not found ENTITY_ID
This means you successfully authenticated and completed the call to your environment, but the entity does not exist. This is an expected error. If you get any other error then there is a problem with your code. Check that your Lattice environment URL and our bearer token are correct.
What's next
- Start building and publishing entities into Lattice.
- See the Lattice sample applications.