我正在构建一个REST API来进行CRUD操作,
我有一个Go结构:
type VisitEntiry struct {
FirstName string `json:"firstname"`
LastName string `json:"lastname"`
UserName string `json:"username"`
PassWord string `json:"password"`
Email string `json:"email"`
}
我可以在数据存储区中保存和检索VisitEntiries。所以我需要编辑访问实体,我想获取数据存储分配一个VisitEntiry使用的ID。我确认使用Google的数据存储仪表板分配了ID,但如何从已检索的VisitEntiry中获取ID?
Cloud you请帮我编写代码以编辑实体。
import (
"encoding/json"
"log"
"net/http"
"golang.org/x/net/context"
"google.golang.org/appengine"
"google.golang.org/appengine/datastore"
)
const KINDNAME = "Vist"
const NAMESPACENAME = "-Test-"
type VisitEntiry struct {
FirstName string `json:"firstname"`
LastName string `json:"lastname"`
UserName string `json:"username"`
PassWord string `json:"password"`
Email string `json:"email"`
}
var visit *VisitEntiry
//SuccessResponse store response
type SuccessResponse struct {
// visit VisitEntiry `json:"entity"`
ID int64 `json:"Id"`
Message string `json:"message"`
}
func init() {
http.HandleFunc("/api/getallvisits", restHandler)
http.HandleFunc("/api/postavisit", restHandler)
}
func restHandler(w http.ResponseWriter, r *http.Request) {
var v VisitEntiry
_ = json.NewDecoder(r.Body).Decode(&v)
json.NewEncoder(w).Encode(v)
visit = &VisitEntiry{
FirstName: v.FirstName,
LastName: v.LastName,
UserName: v.UserName,
PassWord: v.PassWord,
Email: v.Email,
}
switch r.Method {
case "GET":
getallvisitshandler(w, r)
return
case "POST":
putavisthandler(w, r)
return
case "DELETE":
// handleDelete(ed, w, r)
return
default:
//respondErr(w, r, http.StatusNotFound, "is not supported HTTP methods")
}
}
func respond(w http.ResponseWriter, r *http.Request, status int, data interface{}) {
w.WriteHeader(status)
if data != nil {
json.NewEncoder(w).Encode(data)
}
}
func getallvisitshandler(w http.ResponseWriter, r *http.Request) {
var visitslist []VisitEntiry
var ctx context.Context
ctx = appengine.NewContext(r)
ctx, err := appengine.Namespace(ctx, NAMESPACENAME)
if err != nil {
return
}
q := datastore.NewQuery(KINDNAME)
_, err = q.GetAll(ctx, &visitslist)
json.NewEncoder(w).Encode(visitslist)
//log.Printf("%#v Getting values From Datastore - visits ", visitskeys)
}
func putavisthandler(w http.ResponseWriter, r *http.Request) {
var ctx context.Context
keys := make([]*datastore.Key, 1)
ctx = appengine.NewContext(r)
ctx, err := appengine.Namespace(ctx, NAMESPACENAME)
if err != nil {
return
}
keys[0] = datastore.NewIncompleteKey(ctx, KINDNAME, nil)
visitentity, err := datastore.Put(ctx, keys[0], visit)
ID := visitentity.IntID()
value := visitentity.Encode()
//value : = visitentity.Encode()
log.Printf("%#v Getting values From Datastore - visits ", value)
respond(w, r, http.StatusOK, SuccessResponse{ID, "Visit Entity Inserted Successfully! "})
}
答案 0 :(得分:3)
将新实体放入数据存储区时,例如使用datastore.Put()
功能,您将获得指定的密钥作为回报:
func Put(c context.Context, key *Key, src interface{}) (*Key, error)
要更新数据存储区中的现有实体,首先需要从数据存储区获取该实体。
这可能发生在已经知道其密钥并使用datastore.Get()
获取密钥的情况下。在这种情况下,你显然已经拥有了密钥。
您还可以通过运行查询来更新实体。在这种情况下,您最终将通过执行Query.GetAll()
方法获取实体。 Query.GetAll()
返回它返回的实体的键:
func (q *Query) GetAll(c context.Context, dst interface{}) ([]*Key, error)
因此,例如,如果查询返回10个实体(将存储在dst
中),它还将返回10个相应的键作为返回实体的切片。所以你也有钥匙。
另一种选择是使用由Query.Run()
获得的查询迭代器。在这种情况下,您可以通过调用Iterator.Next()
获取实际实体,然后再次返回密钥:
func (t *Iterator) Next(dst interface{}) (*Key, error)
对于客户端更新实体,它必须具有一些唯一标识实体的类型信息,方便其密钥。因此,当客户端请求实体时,服务器也应该发送其密钥。当客户想要更新实体以及更新的数据时,它必须发送密钥。因此,服务器将能够更新由密钥表示的正确实体。
要将密钥发送到客户端,您可以使用Key.Encode()
方法将密钥编码为网络安全字符串。
客户端应该发送回相同的密钥字符串。
服务器可以使用datastore.DecodeKey()
函数将密钥字符串转回*datastore.Key
值。
注意:如果您使用的是数字身份证,并且您知道其类型,则可以选择仅传输数字身份证。您可以使用Key.IntID()
方法获取数字ID。并且您可以使用datastore.NewKey()
从服务器端的数字ID构造密钥,如下所示:
numericID = int64(0) // Get this from the request
key := datastore.NewKey(ctx, KINDNAME, "", numericID, nil)