2016-05-06 6 views
0

iがgolangでREST APIを作っていますし、私はフィールドをフィルタリングするためのサポートを追加したいが、私はそれを実装するための最良の方法を知らない、私はAlbumモデルを表すこのような構造を持っているJSONレスポンスでデータベースからフィールドをフィルタリングする方法は?

type Album struct { 
    ID   uint64 `json:"id"` 
    User   uint64 `json:"user"` 
    Name   string `json:"name"` 
    CreatedDate time.Time `json:"createdDate"` 
    Privacy  string `json:"privacy"` 
    Stars   int  `json:"stars"` 
    PicturesCount int  `json:"picturesCount"` 
} 

と言うことができますAlbum

func GetOne(id uint64, user uint64) (Album, error) { 

    var album Album 

    sql := `SELECT * FROM "album" WHERE "id" = $1 AND "user" = $2;` 

    err := models.DB.QueryRow(sql, id, user).Scan(
    &album.ID, 
    &album.User, 
    &album.Name, 
    &album.CreatedDate, 
    &album.Privacy, 
    &album.Stars, 
    &album.PicturesCount, 
) 

    return album, err 

} 

とクライアントのインスタンスを返す関数は、この
https://api.localhost.com/albums/1/?fields=id,name,privacy

のような要求を発行しましたの

明らかなセキュリティ上の問題はさておき、私の最初に考えたのは、この

func GetOne(id uint64, user uint64, fields string) { 

    var album Album 

    sql := fmt.Sprintf(`SELECT %s FROM "album" WHERE "id" = $1 AND "user" = $2;`, fields) 

    // i don't know what to do after this 

} 

のようなものを使用して、データベース内のフィールドをフィルタリングすることでしたし、私はすべてのフィールドにomitemptyタグを追加すると、前にゼロ値にフィールドを設定すると考えます

  • これは動作しますか?
  • どちらが良い方法ですか?
  • がありますか?
  • 最初の方法を実装するにはどうすればよいですか?

ありがとうございます。あなたの最初の提案(のみ要求されたフィールドを照会)するため

答えて

1

二つのアプローチがある(答えると「どのように私は最初のメソッドを実装するに行くか?」「この作品は希望は?」):

  1. Dynmaically reate (恐らく匿名の)structとそれからencoding/jsonを使用してJSONを生成します。
  2. クエリから取得した*database/sql.RowsをJSONに変換するラッパーを実装します。アプローチのために

(1)、あなたは何とか元のstructからの属性の任意の組み合わせのためのstruct Sを作成する必要があります。 reflect cannot create a new struct type at runtimeとすれば、唯一のチャンスはgenerate them at compile timeです。コンビナトリアル爆発はあなたのバイナリを膨らませるので、そうしないでください。

アプローチ(2.)は慎重に扱うべきであり、最後の手段にすぎません。リクエストされたフィールドのリストを取得し、DBから取得した値を使用してJSONを書き出すことは簡単ではなく、リフレクションには関係しません。しかし、あなたの解はencoding/jsonよりはるかに不安定になるでしょう。

あなたの質問を読むときには、json:"omitempty"構造タグの使用についても考えました。そして、私はそれが望ましい解決策だと思います。これは、メタプログラミングや独自のJSONエンコーダの作成には関係しません。これは良いことです。いくつかのフィールドが欠落している場合(クライアント側はそれを考慮に入れなければならないかもしれません)の場合の意味に気をつけてください。すべてアトリビュート常にを照会して、リダイレクトを使用して不要なものを無効にすることができます。

最後に、上記のすべてのソリューションは最適ではなく、その機能を実装しないことが最善の方法です。私はあなたが属性を可変にする強固な理由があることを願っています。私はあなたの説明に基づいて私の答えをさらに明確にすることを嬉しく思っています。ただし、リソースの属性の1つが大きすぎる場合は、サブリソースである必要があります。

+0

私は 'json:omitempty'と一緒に行って、リクエストされていないすべてのフィールドをリフレクションを使ってゼロの値に設定しましたが、「somefieldsが見つからない場合はどういう意味ですか? – zola

+0

'json:" omitempty "を使わないと' {"name": ""、...} 'を送信しますが、' json: "omitempty" 'の場合は答えに" name "属性が含まれませんvalueは空の文字列です。したがって、JSONを受け取るクライアント(かなり可能性のあるブラウザ)は空の文字列を表示せず、 "name"プロパティには 'undefined'を表示します。予期しない動作が発生する可能性があります。 私の回答は役に立ちましたか?もしそうなら、それを正しいものとしてマークしてください。 –

+0

私はデータベースにnull可能なフィールドがないので、この特定のケースでは問題ありません。 – zola

関連する問題