在Go API中接收到不一致的数据

huangapple go评论72阅读模式
英文:

Receiving inconsistent data in Go api

问题

我正在学习Go语言,并使用Go + Google Firestore作为数据库测试Google Cloud Functions。

在测试过程中,我得到了不一致的响应。

我使用了json Marshaller将Firebase数据转换为Json对象,以便从API返回。这个API托管在Google Cloud Functions中。

// Package p contains an HTTP Cloud Function.
package p

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

	s "strings"

	"encoding/json"

	"cloud.google.com/go/firestore"
	"google.golang.org/api/iterator"
)


func HelloWorld(w http.ResponseWriter, r *http.Request) {
	path := s.Replace(r.URL.Path, "/", "", -1)

	ctx := context.Background()
	client := createClient(ctx)

	iter := client.Collection("profile").Where("publicUrl", "==", path).Documents(ctx)
	for {
		doc, err := iter.Next()
		if err == iterator.Done {
			break
		}
		var publicDTO PublicDTO
		var Profile Profile
		doc.DataTo(&Profile)

		publicDTO.Profile = Profile

		b, err := json.Marshal(publicDTO)
		if err != nil {
			fmt.Println(err)
			return
		}

		w.Header().Set("Content-Type", "application/json")
		w.Write(b)
	}

}

func createClient(ctx context.Context) *firestore.Client {
	projectID := "projectId"

	client, err := firestore.NewClient(ctx, projectID)
	if err != nil {
		log.Fatalf("Failed to create client: %v", err)
	}
	return client
}

type PublicDTO struct {
	Profile       Profile     `json:"profile"`
}

type Profile struct {
	Id           string            `json:"id"`
	FirstName    string            `json:"firstName"`
	LastName     string            `json:"lastName"`
	FullName     string            `json:"fullName"`
	Email        string            `json:"email"`
	ImageUrl     string            `json:"imageUrl"`
	CoverPic     string            `json:"coverPic"`
	Experience   int               `json:"experience"`
	PhoneNumber  string            `json:"phoneNumber"`
	Description  string            `json:"description"`
	Address      string            `json:"address"`
	State        string            `json:"state"`
	Country      string            `json:"country"`
	Dob          map[string]string `json:"dob"`
	Website      string            `json:"website"`
	Reputation   int               `json:"reputation"`
	MemberFrom   map[string]int    `json:"memberFrom"`
	Title        string            `json:"title"`
	Organization string            `json:"organization"`
	Status       string            `json:"status"`
	Setup        int               `json:"setup"`
	Social       map[string]string `json:"social"`
	PublicUrl    string            `json:"publicUrl"`
	Language     []string          `json:"language"`
	Interests    []string          `json:"interests"`
}

但是每次我得到的响应都是不一致的,有些值是缺失的。

英文:

I was learning the Go language and tested Google Cloud Functions with go + Google Firestore as the database.

While I was testing the response I got inconsistent responses.

I have used the json Marshaller to convert Firebase data to Json object to return from the API, this API is hosted in the Google Cloud Functions.

// Package p contains an HTTP Cloud Function.
package p
import (
"context"
"fmt"
"log"
"net/http"
s "strings"
"encoding/json"
"cloud.google.com/go/firestore"
"google.golang.org/api/iterator"
)
func HelloWorld(w http.ResponseWriter, r *http.Request) {
path := s.Replace(r.URL.Path, "/", "", -1)
ctx := context.Background()
client := createClient(ctx)
iter := client.Collection("profile").Where("publicUrl", "==", path).Documents(ctx)
for {
doc, err := iter.Next()
if err == iterator.Done {
break
}
var publicDTO PublicDTO
var Profile Profile
doc.DataTo(&Profile)
publicDTO.Profile = Profile
b, err := json.Marshal(publicDTO)
if err != nil {
fmt.Println(err)
return
}
w.Header().Set("Content-Type", "application/json")
w.Write(b)
}
}
func createClient(ctx context.Context) *firestore.Client {
projectID := "projectId"
client, err := firestore.NewClient(ctx, projectID)
if err != nil {
log.Fatalf("Failed to create client: %v", err)
}
return client
}
type PublicDTO struct {
Profile       Profile     `json:"profile"`
}
type Profile struct {
Id           string            `json:"id"`
FirstName    string            `json:"firstName"`
LastName     string            `json:"lastName"`
FullName     string            `json:"fullName"`
Email        string            `json:"email"`
ImageUrl     string            `json:"imageUrl"`
CoverPic     string            `json:"coverPic"`
Experience   int               `json:"experience"`
PhoneNumber  string            `json:"phoneNumber"`
Description  string            `json:"description"`
Address      string            `json:"address"`
State        string            `json:"state"`
Country      string            `json:"country"`
Dob          map[string]string `json:"dob"`
Website      string            `json:"website"`
Reputation   int               `json:"reputation"`
MemberFrom   map[string]int    `json:"memberFrom"`
Title        string            `json:"title"`
Organization string            `json:"organization"`
Status       string            `json:"status"`
Setup        int               `json:"setup"`
Social       map[string]string `json:"social"`
PublicUrl    string            `json:"publicUrl"`
Language     []string          `json:"language"`
Interests    []string          `json:"interests"`
}

but each time the response i'm getting is inconsistent, some of the values are missing.

答案1

得分: 2

我得到的解决方案在进行编组和解组之后,它按预期工作。

package p

import (
	"context"
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	s "strings"
	"time"

	"cloud.google.com/go/firestore"
	"google.golang.org/api/iterator"
)

var ctx context.Context
var client *firestore.Client

func PublicApi(w http.ResponseWriter, r *http.Request) {
	path := s.Replace(r.URL.Path, "/", "", -1)
	w.Header().Set("Content-Type", "application/json")
	w.Header().Set("Access-Control-Allow-Origin", "*")
	w.Header().Set("Access-Control-Allow-Headers", "*")

	newFsConfigBytes, _ := json.Marshal(getPublicDTO(path))
	w.Write(newFsConfigBytes)
}

func getPublicDTO(path string) (publicDTO publicDTO) {
	ctx = context.Background()
	client = createClient()
	profile, id := getProfiles(path)
	publicDTO.Profile = profile
	publicDTO.MilestoneDTOS = getMilestone(id)
	return
}

func getProfiles(link string) (profile, string) {
	var retVal profile
	var id string
	iter := client.Collection("profile").Where("publicUrl", "==", link).Documents(ctx)
	for {
		doc, err := iter.Next()
		if err == iterator.Done {
			break
		}
		id = doc.Ref.ID
		b, _ := json.Marshal(doc.Data())
		json.Unmarshal(b, &retVal)
	}
	return retVal, id
}

func getMilestone(id string) []milestoneDTOS {
	var retVal []milestoneDTOS
	iter := client.Collection("milestone").Where("userId", "==", id).Documents(ctx)

	for {
		var milestoneDTO milestoneDTOS
		doc, err := iter.Next()
		if err == iterator.Done {
			break
		}
		b, _ := json.Marshal(doc.Data())
		err = json.Unmarshal(b, &milestoneDTO)
		if err != nil {
			fmt.Println(err)
		}
		retVal = append(retVal, milestoneDTO)
	}
	return retVal
}

func createClient() *firestore.Client {
	projectID := "app_id_asda"

	client, err := firestore.NewClient(ctx, projectID)
	if err != nil {
		log.Fatalf("Failed to create client: %v", err)
	}
	return client
}

type profile struct {
	Address          string    `json:"address"`
	City             string    `json:"city"`
	Country          string    `json:"country"`
	CoverPic         string    `json:"coverPic"`
	CreatedBy        string    `json:"createdBy"`
	CreatedDate      int       `json:"createdDate"`
	Description      string    `json:"description"`
	Dob              int64     `json:"dob"`
	Email            string    `json:"email"`
	Enabled          bool      `json:"enabled"`
	Experience       int       `json:"experience"`
	FirstName        string    `json:"firstName"`
	FullName         string    `json:"fullName"`
	FullNameNoSpace  string    `json:"fullNameNoSpace"`
	ImageURL         string    `json:"imageUrl"`
	Interests        []string  `json:"interests"`
	IsEnabled        bool      `json:"isEnabled"`
	Language         string    `json:"language"`
	LastModifiedDate int       `json:"lastModifiedDate"`
	LastName         string    `json:"lastName"`
	LatLng           string    `json:"latLng"`
	MemberFrom       time.Time `json:"memberFrom"`
	ObjectID         string    `json:"objectID"`
	Organization     string    `json:"organization"`
	PhoneNumber      string    `json:"phoneNumber"`
	PlanID           string    `json:"planId"`
	PublicURL        string    `json:"publicUrl"`
	Reputation       int       `json:"reputation"`
	Setup            int       `json:"setup"`
	Social           string    `json:"social"`
	State            string    `json:"state"`
	Status           string    `json:"status"`
	Title            string    `json:"title"`
	Website          string    `json:"website"`
}

type milestoneDTOS struct {
	Category          string    `json:"category"`
	CreatedBy         string    `json:"createdBy"`
	CreatedDate       int       `json:"createdDate"`
	Description       string    `json:"description"`
	Enabled           bool      `json:"enabled"`
	EndDate           time.Time `json:"endDate"`
	IsCurrentPosition bool      `json:"isCurrentPosition"`
	IsEnabled         bool      `json:"isEnabled"`
	LastModifiedBy    time.Time `json:"lastModifiedBy"`
	LastModifiedDate  int       `json:"lastModifiedDate"`
	ObjectID          string    `json:"objectID"`
	Organization      string    `json:"organization"`
	PictureURL        string    `json:"pictureURL"`
	Profile           string    `json:"profile"`
	Score             float64   `json:"score"`
	StartDate         time.Time `json:"startDate"`
	Tags              []string  `json:"tags"`
	Title             string    `json:"title"`
	URL               string    `json:"url"`
	UserID            string    `json:"userId"`
}

type publicDTO struct {
	Profile       profile         `json:"profile"`
	MilestoneDTOS []milestoneDTOS `json:"milestoneDTOS"`
}
英文:

The solution i got after marshal and unmarshal, it works as expected.

package p
import (
"context"
"encoding/json"
"fmt"
"log"
"net/http"
s "strings"
"time"
"cloud.google.com/go/firestore"
"google.golang.org/api/iterator"
)
var ctx context.Context
var client *firestore.Client
func PublicApi(w http.ResponseWriter, r *http.Request) {
path := s.Replace(r.URL.Path, "/", "", -1)
w.Header().Set("Content-Type", "application/json")
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Headers", "*")
newFsConfigBytes, _ := json.Marshal(getPublicDTO(path))
w.Write(newFsConfigBytes)
}
func getPublicDTO(path string) (publicDTO publicDTO) {
ctx = context.Background()
client = createClient()
profile, id := getProfiles(path)
publicDTO.Profile = profile
publicDTO.MilestoneDTOS = getMilestone(id)
return
}
func getProfiles(link string) (profile, string) {
var retVal profile
var id string
iter := client.Collection("profile").Where("publicUrl", "==", link).Documents(ctx)
for {
doc, err := iter.Next()
if err == iterator.Done {
break
}
id = doc.Ref.ID
b, _ := json.Marshal(doc.Data())
json.Unmarshal(b, &retVal)
}
return retVal, id
}
func getMilestone(id string) []milestoneDTOS {
var retVal []milestoneDTOS
iter := client.Collection("milestone").Where("userId", "==", id).Documents(ctx)
for {
var milestoneDTO milestoneDTOS
doc, err := iter.Next()
if err == iterator.Done {
break
}
b, _ := json.Marshal(doc.Data())
err = json.Unmarshal(b, &milestoneDTO)
if err != nil {
fmt.Println(err)
}
retVal = append(retVal, milestoneDTO)
}
return retVal
}
func createClient() *firestore.Client {
projectID := "app_id_asda"
client, err := firestore.NewClient(ctx, projectID)
if err != nil {
log.Fatalf("Failed to create client: %v", err)
}
return client
}
type profile struct {
Address          string    `json:"address"`
City             string    `json:"city"`
Country          string    `json:"country"`
CoverPic         string    `json:"coverPic"`
CreatedBy        string    `json:"createdBy"`
CreatedDate      int       `json:"createdDate"`
Description      string    `json:"description"`
Dob              int64     `json:"dob"`
Email            string    `json:"email"`
Enabled          bool      `json:"enabled"`
Experience       int       `json:"experience"`
FirstName        string    `json:"firstName"`
FullName         string    `json:"fullName"`
FullNameNoSpace  string    `json:"fullNameNoSpace"`
ImageURL         string    `json:"imageUrl"`
Interests        []string  `json:"interests"`
IsEnabled        bool      `json:"isEnabled"`
Language         string    `json:"language"`
LastModifiedDate int       `json:"lastModifiedDate"`
LastName         string    `json:"lastName"`
LatLng           string    `json:"latLng"`
MemberFrom       time.Time `json:"memberFrom"`
ObjectID         string    `json:"objectID"`
Organization     string    `json:"organization"`
PhoneNumber      string    `json:"phoneNumber"`
PlanID           string    `json:"planId"`
PublicURL        string    `json:"publicUrl"`
Reputation       int       `json:"reputation"`
Setup            int       `json:"setup"`
Social           string    `json:"social"`
State            string    `json:"state"`
Status           string    `json:"status"`
Title            string    `json:"title"`
Website          string    `json:"website"`
}
type milestoneDTOS struct {
Category          string    `json:"category"`
CreatedBy         string    `json:"createdBy"`
CreatedDate       int       `json:"createdDate"`
Description       string    `json:"description"`
Enabled           bool      `json:"enabled"`
EndDate           time.Time `json:"endDate"`
IsCurrentPosition bool      `json:"isCurrentPosition"`
IsEnabled         bool      `json:"isEnabled"`
LastModifiedBy    time.Time `json:"lastModifiedBy"`
LastModifiedDate  int       `json:"lastModifiedDate"`
ObjectID          string    `json:"objectID"`
Organization      string    `json:"organization"`
PictureURL        string    `json:"pictureURL"`
Profile           string    `json:"profile"`
Score             float64   `json:"score"`
StartDate         time.Time `json:"startDate"`
Tags              []string  `json:"tags"`
Title             string    `json:"title"`
URL               string    `json:"url"`
UserID            string    `json:"userId"`
}
type publicDTO struct {
Profile       profile         `json:"profile"`
MilestoneDTOS []milestoneDTOS `json:"milestoneDTOS"`
}

huangapple
  • 本文由 发表于 2021年9月6日 18:07:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/69072757.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定