Home > database >  invalid operation - mismatched types string and nil
invalid operation - mismatched types string and nil

Time:12-03

I'm trying to create a Go RESTful API that connects to Google Cloud API's.

An issue is happening, described as: invalid operation: req.ParentId != nil (mismatched types string and nil)

Before creating the local API, I managed to write a Go module that could connect, authenticate, and pull data from Google Cloud. I'm now migrating that module to become a Restful API with paths.

The point of the module was to get a list of all current running Virtual Machines.

Here is the module before changing it to a restful API (which worked):

package main

import (
    "fmt"

    "example.com/compute"

    "bytes"
)

func main() {
    buf := new(bytes.Buffer)

    // Get a message and print it.
    r.HandleFunc("/virtualmachines", ListAllInstances)
    err := compute.ListAllInstances(buf, "unique-string-id")
    if err != nil {
        panic(err)
    }
    fmt.Println(buf.String()) // <======= Print buf contents!
}


// new file:

package compute

// [START compute_instances_list_all]
import (
    "context"
    "fmt"
    "io"

    compute "cloud.google.com/go/compute/apiv1"
    "google.golang.org/api/iterator"
    computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
    "google.golang.org/protobuf/proto"
)

// listAllInstances prints all instances present in a project, grouped by their zone.
func ListAllInstances(w io.Writer, projectID string) error {
    // projectID := "your_project_id"
    ctx := context.Background()
    instancesClient, err := compute.NewInstancesRESTClient(ctx)


    if err != nil {
        return fmt.Errorf("NewInstancesRESTClient: %v", err)
    }
    defer instancesClient.Close()

    // Use the `MaxResults` parameter to limit the number of results that the API returns per response page.
    req := &computepb.AggregatedListInstancesRequest{
        Project:    projectID,
        MaxResults: proto.Uint32(6),
    }

    it := instancesClient.AggregatedList(ctx, req)
    fmt.Fprintf(w, "Instances found:\n")
    // Despite using the `MaxResults` parameter, you don't need to handle the pagination
    // yourself. The returned iterator object handles pagination
    // automatically, returning separated pages as you iterate over the results.

    for {
        pair, err := it.Next()
        if err == iterator.Done {
            break
        }
        if err != nil {
            return err
        }
        instances := pair.Value.Instances
        if len(instances) > 0 {
            fmt.Fprintf(w, "%s\n", pair.Key)
            for _, instance := range instances {
                fmt.Fprintf(w, "- %s %s\n", instance.GetName(), instance.GetMachineType())
            }
        }
    }

    return nil
}

The above worked well, even though it might not like pretty.

Below is my effort to move/transition the module to a Restful API:

package handlers

import (
    "context"
    "fmt"
    "net/http"

    compute "cloud.google.com/go/compute/apiv1"
    "google.golang.org/api/iterator"
    computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
    "google.golang.org/protobuf/proto"
)

// use Google Cloud compute API to get the list of instance virtual machine instances
func (s *Server) getListAllInstances(w http.ResponseWriter, r *http.Request) error {

    ctx := context.Background()
    instancesClient, err := compute.NewInstancesRESTClient(ctx)

    if err != nil {
        return fmt.Errorf("NewInstancesRESTClient: %v", err)
    }
    defer instancesClient.Close()

    // Use the `MaxResults` parameter to limit the number of results that the API returns per response page.
    req := &computepb.AggregatedListInstancesRequest{
        Project:    "unqie-string-id",
        MaxResults: proto.Uint32(16),
    }

    it := instancesClient.AggregatedList(ctx, req)
    fmt.Fprintf(w, "Instances found:\n")
    // Despite using the `MaxResults` parameter, you don't need to handle the pagination
    // yourself. The returned iterator object handles pagination
    // automatically, returning separated pages as you iterate over the results.

    for {
        pair, err := it.Next()
        if err == iterator.Done {
            break
        }
        if err != nil {
            return err
        }
        instances := pair.Value.Instances
        if len(instances) > 0 {
            w.WriteHeader(http.StatusOK)
            fmt.Fprintf(w, "%s\n", pair.Key)
            for _, instance := range instances {
                fmt.Fprintf(w, "- %s %s\n", instance.GetName(), instance.GetMachineType())
            }
        }
    }

    return nil

}

ParentId is the culprit (scroll below for the full error). The string I inserted does not seem to work in the code above. Google Cloud API is trying to figure out what parent ID is for the project. How can I fix the code above?

Il leave this code below just for reference


Here is the path that my api uses to pull the list of active virtual machines

package handlers

import "skeleton/api/middlewares"

func (s *Server) InitializeRoutes() {

    s.Router.HandleFunc("/compute", middlewares.MiddlewaresJSON(s.getListAllInstances)).Methods("GET")

}

here is my MiddlewaresJSON:

package middlewares

import (
    "log"
    "net/http"
)

// intercept the incoming request, and set one of the headers to Content-Type: application/json
func MiddlewaresJSON(next http.HandlerFunc) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        // log the route and method
        log.Println("== route: "   r.URL.Path)
        log.Println("== method: "   r.Method)

        // modify the header
        w.Header().Set("Content-Type", "application/json")
        next(w, r)
    }
}

Here is the full error:

cloud.google.com/go/compute/apiv1
..\go\pkg\mod\cloud.google.com\go@v0.97.0\compute\apiv1\firewall_policies_client.go:684:32: invalid operation: req.ParentId != nil (mismatched typen: req.ParentId != nil (mismatched types string and nil)

Here is the code in the library that error is referring too:

    if req != nil && req.ParentId != nil {
        params.Add("parentId", fmt.Sprintf("%v", req.GetParentId()))
    }

CodePudding user response:

I had the same issue, solved by downgrading of 1 commit :

 go get google.golang.org/genproto@81c1377 

https://github.com/googleapis/go-genproto/commits/main

CodePudding user response:

Is it error in your code or just in publication? in publication I see

req := &computepb.AggregatedListInstancesRequest{
        Project:    "unqie-string-id,
        MaxResults: proto.Uint32(16),
    }

but should be

req := &computepb.AggregatedListInstancesRequest{
        Project:    "unqie-string-id",
        MaxResults: proto.Uint32(16),
    }
  •  Tags:  
  • go
  • Related