Id在使用Go编写的Rest API中返回0。

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

Id is Returning 0 for Rest API with Go

问题

我一直在尝试使用Go构建一些简单的后端REST API,使用Google App Engine和其数据存储,并在前端使用AngularJS。我能够让所有东西都正常工作,但是编辑功能有问题。我不确定为什么JSON无法正确解组。

结构体:

type Article struct {
    Key    int64    `json:"Key" datastore:"-"`
    Title  string
    Text   string   `datastore:",noindex"`
    Author string
    Tags   string
    Posted time.Time
}

当加载文章时,我使用数据存储中的id值填充Key属性。例如:5593215650496512

我将该字段保存在表单的隐藏输入中,并通过HTTP Post将表单内容作为JSON提交到Go后端。

在提交之前,我可以看到Key属性保存了正确的值。以下是表单的代码:

<form name="articleForm" ng-submit="saveArticle(article)">
    <fieldset>
        <input type="hidden" name="key" ng-value="article.Key" />
        <div class="form-group">
            <input class="form-control" ng-model="article.Title" placeholder="Title" name="title" type="text" required autofocus />
            <div class="alert alert-danger" ng-show="articleForm.Title.$invalid && articleForm.Title.$dirty">
                <ul>
                    <li ng-show="articleForm.title.$error.required">this field is required</li>
                </ul>
            </div>
        </div>
        <div class="form-group">
            <wysiwyg 
                name="text"
                textarea-id="articleText" 
                textarea-class="form-control"  
                textarea-height="180px" 
                textarea-name="articleText"
                ng-model="article.Text" 
                enable-bootstrap-title="true" 
                textarea-required>
            </wysiwyg>
            <div class="alert alert-danger" ng-show="articleForm.text.$invalid && articleForm.text.$dirty">
                <ul>
                    <li ng-show="articleForm.text.$error.required">this field is required</li>
                </ul>
            </div>
        </div>
        <div class="form-group">
            <tags-input ng-model="tags"></tags-input>
        </div>
        <button type="submit" ng-disabled="!articleForm.$valid" class="btn btn-primary">
            Save Article
        </button>
    </fieldset>
</form>

在HTTP Post之前,$scope.article对象的值如下:

Author: "Matt Ridley"
Key: "5593215650496512"
Posted: "2015-06-29T12:57:20.833525Z"
Tags: "test,so-cool"
Text: "<div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem at nibh elementum imperdiet. Duis sagittis ipsum. Praesent mauris. Fusce nec tellus sed augue semper porta. Mauris massa. Vestibulum lacinia arcu eget nulla.&nbsp;</div>"
Title: "Example Article 8"

然而,Key属性仍然为0。我可以将该值作为单个id值传递,用于删除和加载,没有问题。

加载只使用id的代码(有效):

var id int64
json.Unmarshal(body, &id)
c.Infof("ID: %v", id)

key := datastore.NewKey(c, "Article", "", id, nil)

编辑带有其他值的代码(无效,id为0):

var article Article
json.Unmarshal(body, &article)
c.Infof("Article:%g", article)
c.Infof("Body:" + string(body))
c.Infof("Key:%v", article.Key)
article.Posted = time.Now()

以下是json.Unmarshal后结构体的转储:

2015/06/29 03:04:08 INFO: Article:{%!g(int64=0) %!g(string=Example Article 8) %!g(string=<div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem at nibh elementum imperdiet. Duis sagittis ipsum. Praesent mauris. Fusce nec tellus sed augue semper porta. Mauris massa. Vestibulum lacinia arcu eget nulla.&nbsp;</div>) %!g(string=Matt Ridley) %!g(string=test,so-cool) {%!g(int64=63570890170) %!g(int32=842211000) %!g(*time.Location=&{UTC [] [] 0 0 <nil>})}}

Key的日志记录如下:

2015/06/29 03:04:08 INFO: Key:0

body的转储:

2015/06/29 14:00:34 INFO: Body:{"Key":"5593215650496512","Title":"Example Article 8","Text":"<div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem at nibh elementum imperdiet. Duis sagittis ipsum. Praesent mauris. Fusce nec tellus sed augue semper porta. Mauris massa. Vestibulum lacinia arcu eget nulla.&nbsp;</div>","Author":"Matt Ridley","Tags":"test,so-cool","Posted":"2015-06-29T13:28:06.168062Z"}

我已经为此问题苦苦思索了几天,所以任何见解都将不胜感激。谢谢!

英文:

I have been trying to build some simple backend REST API using Go using the Google App Engine and its datastore and AngularJS on the frontend. I was able to get everything working but the edit. And I am not sure why the JSON is not un-marshaling correctly.

Struct:

type Article struct {
    Key    int64    `json:&quot;Key&quot; datastore:&quot;-&quot;`
    Title  string
    Text   string   `datastore:&quot;,noindex&quot;`
    Author string
    Tags   string
    Posted time.Time
}

When I load the article, I populate the Key property with the id value from the datastore. Example: 5593215650496512

I keep that field in a hidden input on my form, and submit the form's content as JSON through an HTTP Post to the Go backend.

Before the submit, I can see that the Key holds the proper value. Here is the form though:

                &lt;form name=&quot;articleForm&quot; ng-submit=&quot;saveArticle(article)&quot;&gt;
                    &lt;fieldset&gt;
                        &lt;input type=&quot;hidden&quot; name=&quot;key&quot; ng-value=&quot;article.Key&quot; /&gt;
                        &lt;div class=&quot;form-group&quot;&gt;
                            &lt;input class=&quot;form-control&quot; ng-model=&quot;article.Title&quot; placeholder=&quot;Title&quot; name=&quot;title&quot; type=&quot;text&quot; required autofocus /&gt;
                            &lt;div class=&quot;alert alert-danger&quot; ng-show=&quot;articleForm.Title.$invalid &amp;&amp; articleForm.Title.$dirty&quot;&gt;
                                &lt;ul&gt;
                                    &lt;li ng-show=&quot;articleForm.title.$error.required&quot;&gt;this field is required&lt;/li&gt;
                                &lt;/ul&gt;
                            &lt;/div&gt;
                        &lt;/div&gt;
                        &lt;div class=&quot;form-group&quot;&gt;
                            &lt;wysiwyg 
                                name=&quot;text&quot;
                                textarea-id=&quot;articleText&quot; 
                                textarea-class=&quot;form-control&quot;  
                                textarea-height=&quot;180px&quot; 
                                textarea-name=&quot;articleText&quot;
                                ng-model=&quot;article.Text&quot; 
                                enable-bootstrap-title=&quot;true&quot; 
                                textarea-required&gt;
                            &lt;/wysiwyg&gt;
                            &lt;div class=&quot;alert alert-danger&quot; ng-show=&quot;articleForm.text.$invalid &amp;&amp; articleForm.text.$dirty&quot;&gt;
                                &lt;ul&gt;
                                    &lt;li ng-show=&quot;articleForm.text.$error.required&quot;&gt;this field is required&lt;/li&gt;
                                &lt;/ul&gt;
                            &lt;/div&gt;
                        &lt;/div&gt;
                        &lt;div class=&quot;form-group&quot;&gt;
                            &lt;tags-input ng-model=&quot;tags&quot;&gt;&lt;/tags-input&gt;
                        &lt;/div&gt;
                        &lt;button type=&quot;submit&quot; ng-disabled=&quot;!articleForm.$valid&quot; class=&quot;btn btn-primary&quot;&gt;
                            Save Article
                        &lt;/button&gt;
                    &lt;/fieldset&gt;
                &lt;/form&gt;

The $scope.article object right before the http post:

> Author: "Matt Ridley"
Key: "5593215650496512"
Posted: "2015-06-29T12:57:20.833525Z"
Tags: "test,so-cool"
Text: "<div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem at nibh elementum imperdiet. Duis sagittis ipsum. Praesent mauris. Fusce nec tellus sed augue semper porta. Mauris massa. Vestibulum lacinia arcu eget nulla.&nbsp;</div>"
Title: "Example Article 8"

However, the Key property remains 0. I am able to pass that value in as a single id value with no issue for delete and load.

Code for loading just the id (this was the load version, it works):

var id int64
json.Unmarshal(body, &amp;id)
c.Infof(&quot;ID: %v&quot;, id)

key := datastore.NewKey(c, &quot;Article&quot;, &quot;&quot;, id, nil)

Code for the edit with additional values (does not work, id = 0):

var article Article
json.Unmarshal(body, &amp;article)
c.Infof(&quot;Article:%g&quot;, article)
c.Infof(&quot;Body:&quot; + string(body))
c.Infof(&quot;Key:%v&quot;, article.Key)
article.Posted = time.Now()

Here is a dump of the struct after json.Unmarshal:

> 2015/06/29 03:04:08 INFO: Article:{%!g(int64=0) %!g(string=Example Article 8)
> %!g(string=<div>Lorem ipsum dolor sit amet, consectetur adipiscing
> elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam.
> Sed nisi. Nulla quis sem at nibh elementum imperdiet. Duis sagittis
> ipsum. Praesent mauris. Fusce nec tellus sed augue semper porta.
> Mauris massa. Vestibulum lacinia arcu eget
> nulla.&nbsp;</div>) %!g(string=Matt Ridley)
> %!g(string=test,so-cool) {%!g(int64=63570890170) %!g(int32=842211000)
> %!g(*time.Location=&{UTC [] [] 0 0 <nil>})}}

Key is logging as...

> 2015/06/29 03:04:08 INFO: Key:0

The body dump:

> 2015/06/29 14:00:34 INFO: Body:{"Key":"5593215650496512","Title":"Example Article 8","Text":"<div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem at nibh elementum imperdiet. Duis sagittis ipsum. Praesent mauris. Fusce nec tellus sed augue semper porta. Mauris massa. Vestibulum lacinia arcu eget nulla.&nbsp;</div>","Author":"Matt Ridley","Tags":"test,so-cool","Posted":"2015-06-29T13:28:06.168062Z"}

I have been banging my head on this for a few days, so any insight would be appreciated. Thanks!

答案1

得分: 1

你在对文章进行解组(Unmarshal)时忽略了错误。你应该看到json: cannot unmarshal string into Go value of type int64的错误提示,因为在请求体中的Key值被格式化为字符串。

如果这是你期望的结果,你可以通过在标签中添加string选项来告诉json包使用它:

type Article struct {
    Key    int64    `json:"Key,string" datastore:"-"`
    Title  string
    Text   string   `datastore:",noindex"`
    Author string
    Tags   string
    Posted time.Time
}
英文:

You're ignoring the error when you Unmarshal into your Article. You should see json: cannot unmarshal string into Go value of type int64, because the Key value in the body is being formatted as a string.

If it is what you expect, then you can tell the json package to make use of it by adding the string option to the tag:

type Article struct {
    Key    int64    `json:&quot;Key,string&quot; datastore:&quot;-&quot;`
    Title  string
    Text   string   `datastore:&quot;,noindex&quot;`
    Author string
    Tags   string
    Posted time.Time
}

huangapple
  • 本文由 发表于 2015年6月29日 11:13:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/31107212.html
匿名

发表评论

匿名网友

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

确定