2017-12-29 26 views
1

golangに送信中にbody jsonに省略された値が含まれているという安らかな要求に取り組んでいます。設定されていない値はgolang構造体をデフォルト値にします。ですから、パッチ要求省略データを処理する解決策があるかどうかを知りたいのですが?golangで未定義の値を使ってパッチリクエストを処理する方法

私が知っているように、string/intのような基本型はgolangではnullableにできません。設定されていない値のパッチ要求に対処するための異なるアプローチがあります。たとえば、次のように値が設定されている場合

  1. ヌル問題

    type User struct { 
        Name *string 
    } 
    
  2. に対処するためにポインタを使用しては見ることmap[string][]interface{}を使用してNULL可能なライブラリ

    type User struct { 
        Name sql.NullString 
    } 
    
  3. を使用して

構造体内のnull値を扱うためのよりよい解決法はありますか?この3はnull値を処理するために回避する必要があるからです。

+0

これ以外の唯一の可能性は、パッチを当てたい値がある場合です。 dbから、あなたはそれを非整列化することができ、jsonで省略されたフィールドは値に上書きされません。 https://play.golang.org/p/zyTtrqyRZJp – mkopriva

答えて

1

omitemptyタグとともにポインタを使用します。このようにして、未設定値nilと意図的なゼロ値( ""、false、0)を区別することができます。

type User struct { 
    Name *string `json:"name,omitempty"` 
} 

Playground

+0

あなたの提案をありがとう。はい、それは可能な方法です。しかし、nullable libを使用することを提案しない理由を知りたいのですが? p。どの解決方法が良いか考えていますが、どちらが良いか分かりません。 –

+0

もう一つの依存関係です。それがあなたにとって問題になるかどうかは分かりません。私はそれが標準であることを示唆した方法(libsは必要ありません)。 –

+0

そして、ポインタはヌル可能な(うまくいけば、 'nil'可能な)型であると考えると、第三者のライブラリを使うのは馬鹿げているようです。 – Adrian

0

別の解決策は、あなた自身のタイプを書いて、その値がNULLフィールドが設定されているnullある場合json.Unmarshaller

package main 

import (
    "encoding/json" 
    "fmt" 
) 

type NullString struct { 
    Data string 
    Null bool 
} 

func (ns *NullString) UnmarshalJSON(d []byte) error { 
    if string(d) == "null" { 
     // this is based on your need. you may add a new field here 
     ns.Null = true 
     return nil 
    } 
    return json.Unmarshal(d, &ns.Data) 
} 

type Test struct { 
    Data1 NullString `json:"data1"` 
    Data2 NullString `json:"data2"` 
    Data3 NullString `json:"data3"` 
} 

const t = `{"data1":null, "data2":"string"}` 

func main() { 
    p := Test{} 
    json.Unmarshal([]byte(t), &p) 
    fmt.Printf("%+v", p) 
} 

結果は{Data1:{Data: Null:true} Data2:{Data:string Null:false} Data3:{Data: Null:false}}で実装しています。また、必要に応じて、この構造体に追加のフィールドを追加することもできます。たとえば、関数が呼び出されたかどうかを追跡するフィールドです。

ps:構造体からjsonへの逆の場合は、json.Marshallerも参照してください。

playground

3

あなたがRESTfulな方法でPATCHを使用している場合、それはそれはいくつかの既存のデータを更新し、フィールドだけを上書きしています意味リクエストボディに含まれています。つまり、実際にフィールドが設定されているかどうかを知る必要はありません。あなただけ手つかずの他のものを残したまま、JSONで発見されたすべてのフィールドを置き換えるために、それの上に正規のオブジェクトとアンマーシャリングを読み込むことができます。

canonObj := getObjectFromDBOrSomething() 
err := json.NewDecoder(req.Body).Decode(canonObj) 

これはリクエストからフィールドを持つcanonObj内の任意のフィールドを上書きしますが、どんなますリクエスト内のでない場合は、には触れません。

+0

このメソッドは本当に魔法です、このような仕事をすることはできません。 –

+0

渡すのを忘れないでくださいそれはポインタでないかもしれないのでアドレス( '&canonObj')。 – icza

+0

アドレスがポインタでない場合*を渡します。既にポインタの場合はそのまま渡してください。 – Adrian

関連する問題