Google APIs Client Library for Go

repository·main·Indexed 26 days ago

https://github.com/googleapis/google-api-go-client

Auto-generated Go client libraries for accessing various Google APIs. The library provides tools for interacting with Google services, including the google-api-go-generator for creating clients from discovery documents. It supports authentication via Application Default Credentials (ADC), JSON key files, OAuth2 TokenSource, and API keys. Note that for GCP-specific services like Datastore or Pub/Sub, the dedicated Cloud Client Libraries for Go are recommended.

Tokens
5.4K
Snippets
18
Records
30
Agent score
85%

What's inside google-api-go-client

  1. Authenticate using 3-legged OAuth

    main

    For applications that redirect users to a website to obtain access tokens, create an oauth2.Config. You will need a ClientID and ClientSecret from the Google Cloud Console. Use google.Endpoint for the endpoint and the specific API's scope (e.g., urlshortener.UrlshortenerScope).

        var config = &oauth2.Config{
            ClientID:     "", // from https://console.developers.google.com/project/<your-project-id>/apiui/credential
            ClientSecret: "", // from https://console.developers.google.com/project/<your-project-id>/apiui/credential
            Endpoint:     google.Endpoint,
            Scopes:       []string{urlshortener.UrlshortenerScope},
        }
  2. Authorize using Application Default Credentials (ADC)

    main
    By default, the client libraries use Google Application Default Credentials. This allows your application to run in many environments (like GCE, GKE, or local environments with GOOGLE_APPLICATION_CREDENTIALS set) without explicit configuration in your code.
  3. Install Google API client libraries

    main

    Install specific Google API client libraries using go get. Each service is contained in its own package. For example, to install the Tasks, Moderator, or URL Shortener APIs, run:

    $ go get google.golang.org/api/tasks/v1
    $ go get google.golang.org/api/moderator/v1
    $ go get google.golang.org/api/urlshortener/v1
  4. Test HTTP services using fakes with httptest

    main

    Since google.golang.org/api services are HTTP-based and return concrete types rather than interfaces, you can test your code by serving an in-memory server using the standard library's httptest package.

    To redirect the client to your fake server instead of the live Google API, use option.WithEndpoint(ts.URL) when calling the service constructor. It is also recommended to use option.WithoutAuthentication() in your tests to avoid credential issues when hitting a local fake server.

    import (
        "context"
        "encoding/json"
        "net/http"
        "net/http/httptest"
        "testing"
    
        "google.golang.org/api/option"
        "google.golang.org/api/translate/v3"
    )
    
    func TestTranslateText(t *testing.T) {
        ctx := context.Background()
        // 1. Create the fake server
        ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
            resp := &translate.TranslateTextResponse{
                Translations: []*translate.Translation{
                    {TranslatedText: "Hello World"},
                },
            }
            b, err := json.Marshal(resp)
            if err != nil {
                http.Error(w, "unable to marshal request: "+err.Error(), http.StatusBadRequest)
                return
            }
            w.Write(b)
        }))
        defer ts.Close()
    
        // 2. Initialize the service pointing to the fake endpoint
        svc, err := translate.NewService(ctx, option.WithoutAuthentication(), option.WithEndpoint(ts.URL))
        if err != nil {
            t.Fatalf("unable to create client: %v", err)
        }
    
        // 3. Call your production code
        text, err := TranslateText(svc, "Hola Mundo", "en-US")
        if err != nil {
            t.Fatal(err)
        }
        if text != "Hello World" {
            t.Fatalf("got %q, want Hello World", text)
        }
    }
  5. Test using mocks via the Facade pattern

    main

    The client libraries in google.golang.org/api use a builder pattern for requests, which makes creating low-level interfaces for mocking difficult and tedious.

    Instead, use the Facade pattern:

    1. Define a high-level interface that represents the specific business logic you need (e.g., TranslateText(text, language string)).
    2. Create a concrete wrapper struct that holds the actual *service.Service and implements your interface by calling the complex builder methods.
    3. In your tests, pass a lightweight mock implementation of your high-level interface instead of the real service.
    // 1. Define a high-level interface (The Facade)
    type TranslateService interface {
        TranslateText(text, language string) (string, error)
    }
    
    // 2. Create a wrapper for production use
    type translateService struct {
        svc *translate.Service
    }
    
    func (t *translateService) TranslateText(text, language string) (string, error) {
        parent := fmt.Sprintf("projects/%s/locations/global", os.Getenv("GOOGLE_CLOUD_PROJECT"))
        resp, err := t.svc.Projects.Locations.TranslateText(parent, &translate.TranslateTextRequest{
            TargetLanguageCode: language,
            Contents:           []string{text},
        }).Do()
        if err != nil {
            return "", err
        }
        return resp.Translations[0].TranslatedText, nil
    }
    
    // 3. Create a mock for testing
    type mockService struct{}
    
    func (*mockService) TranslateText(text, language string) (string, error) {
        return "Hello World", nil
    }
    
    func TestTranslateTextHighLevel(t *testing.T) {
        svc := &mockService{}
        text, err := TranslateTextHighLevel(svc, "Hola Mundo", "en-US")
        // ... assert results
    }
  6. Authenticate using API Keys

    main

    If an API requires an API key, use transport.APIKey from the google.golang.org/api/googleapi/transport package. You must wrap the key in an http.Client and pass it via context using the oauth2.HTTPClient key.

        ctx := context.WithValue(context.Background(), oauth2.HTTPClient, &http.Client{
            Transport: &transport.APIKey{Key: developerKey},
        })
        oauthConfig := &oauth2.Config{ .... }
        var token *oauth2.Token = .... // via cache, or oauthConfig.Exchange
        httpClient := oauthConfig.Client(ctx, token)
        svc, err := urlshortener.New(httpClient)
        ...
  7. Instantiate an API service

    main

    After installing the package, import it and use the New function provided by the API package. The New function requires an *http.Client that is configured with appropriate Google authentication. The package name used in your code is typically the API name without the version number.

    Example for urlshortener/v1:

    package main
    
    import (
        "context"
        "golang.org/x/oauth2"
        "golang.org/x/oauth2/google"
        "google.golang.org/api/urlshortener/v1"
    )
    
    func main() {
        // httpClient must be an authorized client
        var httpClient *http.Client
        svc, err := urlshortener.New(httpClient)
        if err != nil {
            // handle error
        }
        _ = svc
    }