亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

使用 PostgreSQL 和 json-api 的發布請求返回一個空體

使用 PostgreSQL 和 json-api 的發布請求返回一個空體

Go
莫回無 2023-06-12 16:56:50
在 POST 請求之后,我期望將最后插入的記錄編組到 json 中,但返回一個空體。我做的不好嗎?package modelsimport (    "encoding/json"    "errors"    "flag"    "fmt"    "log"    "net/http"    "strconv"    "github.com/go-chi/chi"    "github.com/google/jsonapi"    "github.com/thedevsaddam/renderer"    "github.com/xo/dburl")var rnd = renderer.New()var flagVerbose = flag.Bool("v", false, "verbose")var FlagURL = flag.String("url", "postgres://postgres:@127.0.0.1/sweb", "url")// Page represents a row from 'public.pages'.type Page struct {    Tag   string `jsonapi:"attr,tag"`      // tag    Body  string `jsonapi:"attr,body"`     // body    Slug  string `jsonapi:"attr,slug"`     // slug    Title string `jsonapi:"attr,title"`    // title    ID    int    `jsonapi:"primary,pages"` // id    Link  string `jsonapi:"attr,link"`     // link    // xo fields    _exists, _deleted bool}func (page Page) JSONAPILinks() *jsonapi.Links {    return &jsonapi.Links{        "self": fmt.Sprintf("https://%d", page.ID),    }}我相信這是罪魁禍首。插入記錄后,它應該返回指定的最后插入的記錄。func (p *Page) PInsert(db XODB) (*Page, error) {    var err error    // if already exist, bail    if p._exists {        return p, errors.New("insert failed: already exists")    }    // sql insert query, primary key provided by sequence    const sqlstr = `INSERT INTO public.pages (` +        `tag, body, slug, title` +        `) VALUES (` +        `$1, $2, $3, $4` +        `) RETURNING id, tag, body, title`    // run query    XOLog(sqlstr, p.Tag, p.Body, p.Slug, p.Title)    err = db.QueryRow(sqlstr, p.Tag, p.Body, p.Slug, p.Title).Scan(&p.ID, &p.Tag, &p.Body, &p.Title)    if err != nil {        return p, err    }    // set existence    p._exists = true    return p, nil}更新更新數據庫中的頁面并返回最后插入的記錄。這同樣適用于更新功能這是我認為問題發生的最后一個功能。最后插入的記錄應該編組到 json 中。
查看完整描述

1 回答

?
www說

TA貢獻1775條經驗 獲得超8個贊

您的最后一段代碼包含許多錯誤。相關部分(沒有無用和混淆的 Printlns)是:


p, err := page.PSave(db)

if err != nil {

    if err := jsonapi.MarshalPayload(w, p); err != nil {

        http.Error(w, err.Error(), http.StatusInternalServerError)

    }

}


w.Header().Set("Content-Type", jsonapi.MediaType)

w.WriteHeader(http.StatusCreated)

主要的錯誤是json.MarshalPayload它只在err != nil. 換句話說,只有在保存失敗時才序列化該頁面。


第二個錯誤是jsonapi.MarshalPayload將Write調用http.ResponseWriter. 這會將所有后續調用 Header().Set變成WriteHeader空操作。


更正確的代碼看起來像這樣。


// 1. Save the page in the database, bail on error

p, err := page.PSave(db)

if err != nil {

    http.Error(w, err.Error(), http.StatusInternalServerError)

    return 

}


// 2. Marshal the page into an intermediate buffer, bail on error

var buf bytes.Buffer

if err := jsonapi.MarshalPayload(&buf, p); err != nil {

    http.Error(w, err.Error(), http.StatusInternalServerError)

    return 

}


// 3. Write the entire response; failures to write the intermediate buffer

// cannot be communicated over HTTP

w.Header().Set("Content-Type", jsonapi.MediaType)

w.WriteHeader(http.StatusCreated)

if _, err := buf.WriteTo(w); err != nil {

    log.Printf("failed to write response: %v", err)

    return 

}


查看完整回答
反對 回復 2023-06-12
  • 1 回答
  • 0 關注
  • 123 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號