ক্ষেত্রগুলি স্ট্রাক্ট থেকে সরানো বা এটিকে JSON প্রতিক্রিয়াতে লুকিয়ে রাখা


180

আমি গোতে একটি এপিআই তৈরি করেছি যা বলা হওয়ার পরে, একটি কোয়েরি সম্পাদন করে, একটি কাঠামোর একটি উদাহরণ তৈরি করে এবং তারপরে কলারে ফেরত পাঠানোর আগে সেই স্ট্রোকটিকে JSON হিসাবে এনকোড করে দেয়। আমি এখন কলারকে "ক্ষেত্রগুলি" জিইটি প্যারামিটারে পাস করে যে নির্দিষ্ট ক্ষেত্রগুলি তারা ফেরত চাইবে তা চয়ন করতে সক্ষম হতে চাই।

এর অর্থ ক্ষেত্রের মান (গুলি) এর উপর নির্ভর করে আমার স্ট্রাক্ট পরিবর্তন হবে। কাঠামো থেকে ক্ষেত্রগুলি সরানোর কোনও উপায় আছে কি? অথবা অন্তত গতিশীলভাবে JSON প্রতিক্রিয়া এগুলি লুকান? (দ্রষ্টব্য: মাঝে মাঝে আমার খালি মূল্য থাকে তাই জেএসওএন অমিটেম্পি ট্যাগটি এখানে কাজ করবে না) যদি এগুলির দুটিও সম্ভব না হয় তবে এটি পরিচালনা করার জন্য আরও ভাল উপায়ের জন্য কোনও পরামর্শ থাকতে পারে? আগাম ধন্যবাদ.

আমি যে স্ট্র্টগুলি ব্যবহার করছি তার একটি ছোট সংস্করণ নীচে রয়েছে:

type SearchResult struct {
    Date        string      `json:"date"`
    IdCompany   int         `json:"idCompany"`
    Company     string      `json:"company"`
    IdIndustry  interface{} `json:"idIndustry"`
    Industry    string      `json:"industry"`
    IdContinent interface{} `json:"idContinent"`
    Continent   string      `json:"continent"`
    IdCountry   interface{} `json:"idCountry"`
    Country     string      `json:"country"`
    IdState     interface{} `json:"idState"`
    State       string      `json:"state"`
    IdCity      interface{} `json:"idCity"`
    City        string      `json:"city"`
} //SearchResult

type SearchResults struct {
    NumberResults int            `json:"numberResults"`
    Results       []SearchResult `json:"results"`
} //type SearchResults

আমি তখন এনকোড করে আছি এবং প্রতিক্রিয়াটিকে এভাবে আউটপুট করি:

err := json.NewEncoder(c.ResponseWriter).Encode(&msg)

7
@ জ্যাকব, পুয়েরকিতোবিওর আপডেট হওয়া উত্তর অনুসারে, আমি মনে করি আপনি প্রশ্নটি ভুলভাবে পড়েছেন। (বর্তমানে) স্বীকৃত আপনার প্রশ্নের "সঠিক উত্তর" নাও হতে পারে , তবে এখানে যা জিজ্ঞাসা করা হয়েছে তার পক্ষে! (বর্তমানে) সর্বাধিক ভোট দেওয়া উত্তরটি আপনার প্রশ্নের উত্তর দিতে পারে তবে এটির পুরোপুরি অনুপযুক্ত !
ডেভ সি

উত্তর:


273

সম্পাদনা: আমি কয়েকটি ডাউনওয়েট লক্ষ্য করেছি এবং এই প্রশ্নোত্তরটির দিকে আবার নজর রেখেছি। বেশিরভাগ লোক মনে করছেন বলে মনে হয় যে ওপি কলার সরবরাহকারী ক্ষেত্রগুলির তালিকার ভিত্তিতে ক্ষেত্রগুলি গতিশীলভাবে নির্বাচন করতে বলেছিল । আপনি স্ট্যাটিকালি সংজ্ঞায়িত জসন স্ট্রাক ট্যাগ দিয়ে এটি করতে পারবেন না।

আপনি যা চান তা যদি সর্বদা জেসন-এনকোডে কোনও ক্ষেত্র এড়িয়ে যান তবে অবশ্যই json:"-"ক্ষেত্রটিকে উপেক্ষা করার জন্য অবশ্যই ব্যবহার করুন (এছাড়াও নোট করুন যে এটি নয় জেসন-এনকোডে আপনার ক্ষেত্রটি অপরিবর্তিত থাকলে প্রয়োজন - সেই ক্ষেত্রগুলি সবসময় জসন এনকোডার দ্বারা উপেক্ষা করা হয়)। তবে ওপি-র প্রশ্ন নয়।

json:"-"উত্তরের মন্তব্যটি উদ্ধৃত করতে :

এটি [ json:"-"উত্তর] বেশিরভাগ লোকেরা এখানে অনুসন্ধান শেষ করে শেষ করতে চাইবে, তবে এটি প্রশ্নের উত্তর নয়।


আমি এই ক্ষেত্রে স্ট্রাক্টের পরিবর্তে একটি মানচিত্র [স্ট্রিং] ইন্টারফেস use use ব্যবহার করব। আপনি সহজেই কল করে ক্ষেত্রগুলি সরাতে পারেনdelete মানচিত্রে বিল্ট-ইন ।

এটি হ'ল, যদি আপনি কেবল প্রথমে অনুরোধ করা ক্ষেত্রগুলির জন্য অনুসন্ধান করতে না পারেন।


4
আপনি সম্ভবত আপনার টাইপ সংজ্ঞা পুরোপুরি ফেলে দিতে চান না। এটি লাইনটি হতাশ হতে চলেছে যেমন আপনি যখন এই ধরণের অন্যান্য পদ্ধতিগুলি লিখতে চান যা এই ক্ষেত্রগুলিতে অ্যাক্সেস করে। মধ্যবর্তী ব্যবহারটি অর্থবোধ map[string]interface{}করে, তবে এটির জন্য আপনার ধরণের সংজ্ঞাটি ফেলে দেওয়া দরকার হয় না।
জোরেলি

1
অন্য উত্তরটি হ'ল এই প্রশ্নের আসল উত্তর।
জ্যাকব

1
মোছার সম্ভাব্য অপূর্ণতা হ'ল আপনি কখনও কখনও আপনার স্ট্রাক্ট (মানচিত্র) এর একাধিক জসন ভিউ সমর্থন করতে পারেন। উদাহরণস্বরূপ সংবেদনশীল ক্ষেত্রবিহীন ক্লায়েন্টের জন্য জসন ভিউ এবং সংবেদনশীল ক্ষেত্রের সাথে ডাটাবেসগুলির জন্য জসন ভিউ। ভাগ্যক্রমে স্ট্রাকটি ব্যবহার করা এখনও সম্ভব - আমার উত্তরটি একবার দেখুন।
অ্যাডাম কুরকিউইচ

এটি আমার পক্ষে কাজ করে কারণ আমার কেবলমাত্র একটি নির্দিষ্ট প্রয়োজন ছিল Idতবে, পুরো জেসন স্ট্রাক্টটি ফিরে আসতে চাই না। এর জন্য ধন্যবাদ!
লুই মিরান্ডা

154

`json:" - "` ব্যবহার করুন `

// Field is ignored by this package.
Field int `json:"-"`

// Field appears in JSON as key "myName".
Field int `json:"myName"`

// Field appears in JSON as key "myName" and
// the field is omitted from the object if its value is empty,
// as defined above.
Field int `json:"myName,omitempty"`

// Field appears in JSON as key "Field" (the default), but
// the field is skipped if empty.
// Note the leading comma.
Field int `json:",omitempty"`

ডক: http://golang.org/pkg/encoding/json/# মার্শাল


14
আমি @ জ্যাকবকে দ্বিমত করব কারণ ওপি জানিয়েছে যে তারা এপিআই-তে কোয়েরি স্ট্রিং এন্ট্রির ভিত্তিতে আউটপুট ক্ষেত্রগুলিকে গতিশীলভাবে নিয়ন্ত্রণ করতে চায়। উদাহরণস্বরূপ, যদি এপিআইতে কলকারী কেবল শিল্প এবং দেশের জন্য জিজ্ঞাসা করে তবে আপনার তখন বাকি অংশটি সরিয়ে ফেলতে হবে। এই কারণেই "টিকযুক্ত" উত্তরটিকে এই প্রশ্নের উত্তর হিসাবে চিহ্নিত করা হয়েছে। এই সর্বাধিক ভোট দেওয়া উত্তরটি ক্ষেত্রগুলি স্পষ্টভাবে কখনও কোনও বিল্টিন-জসন-মার্শালার - কখনও উপলভ্য নয় - এর জন্য উপলভ্য king আপনি যদি এটি গতিশীলভাবে চান তবে টিকযুক্ত উত্তরটি উত্তর।
eduncan911

11
সন্ধান থেকে এখানে শেষ হওয়া বেশিরভাগ লোকই এই উত্তরটি চাইবে, তবে এটি প্রশ্নের উত্তর নয়।
ফিলিপ হাগলুন্ড

5
ইতিমধ্যে উল্লিখিত হিসাবে ওপি গতিশীলভাবে একটি ডিটিও গঠনের জন্য একটি পদ্ধতি জিজ্ঞাসা করছে।
কোডপুশার

53

এটি করার আরেকটি উপায় হ'ল একটি স্ট্রাক্ট ,omitempty ট্যাগ সহ পয়েন্টারগুলির । পয়েন্টার যদি শূন্য থাকে তবে ক্ষেত্রগুলি মার্শাল হবে না।

এই পদ্ধতিতে অতিরিক্ত প্রতিবিম্ব বা মানচিত্রের অকার্যকর ব্যবহারের প্রয়োজন হবে না।

এই পদ্ধতিটি ব্যবহার করে জোড়েলি হিসাবে একই উদাহরণ: http://play.golang.org/p/JJNa0m2_nw


3
+1 সম্পূর্ণ সম্মত হন। আমি অন্তর্নির্মিত মার্শেলারদের সাথে এই নিয়মটি / কৌশলটি সর্বদা ব্যবহার করি (এবং এমনকি এই নিয়মের ভিত্তিতে একটি সিএসভি পাঠক / লেখকও তৈরি করেছি! - আমি অন্য কোনও সিএসভি গো প্যাকেজ হিসাবে ওপেন সোর্স পেতে পারি)। ওপি তখন কেবল * দেশের মানটিকে শূন্য করতে পারে না এবং এটি বাদ দেওয়া হবে। এবং আশ্চর্যজনক যে আপনি একটি দুর্দান্ত সরবরাহ করেছেন, y টাইপ প্লে.আওলংও।
eduncan911

2
অবশ্যই সেই পদ্ধতির প্রতিবিম্বের প্রয়োজন, স্ট্ডলিবের জসন-টু-স্ট্রাক্ট মার্শালিং সর্বদা প্রতিবিম্ব ব্যবহার করে (আসলে এটি সর্বদা প্রতিবিম্ব সময়কাল, মানচিত্র বা কাঠামো বা যে কোনও কিছু ব্যবহার করে)।
এমএনএ

হ্যাঁ, তবে এর জন্য ইন্টারফেসগুলি ব্যবহার করে অতিরিক্ত প্রতিবিম্বের প্রয়োজন হয় না , যা অন্য কয়েকটি উত্তর সুপারিশ করে।
ড্রুসকা

14

reflectফিল্ড ট্যাগগুলি প্রতিফলিত করে এবং jsonট্যাগ মান নির্বাচন করে আপনি যে ক্ষেত্রগুলি চান তা নির্বাচন করতে আপনি প্যাকেজটি ব্যবহার করতে পারেন । আপনার অনুসন্ধান ফলাফলের ধরণে এমন একটি পদ্ধতি নির্ধারণ করুন যা আপনি চান ক্ষেত্রগুলি নির্বাচন করে এবং তাদের হিসাবে ফেরত map[string]interface{}পাঠান, এবং তারপরে মার্শাল যা অনুসন্ধানের ফলাফলগুলির পরিবর্তে নিজেই গঠন করবে। আপনি কীভাবে সেই পদ্ধতিটি সংজ্ঞায়িত করতে পারেন তার একটি উদাহরণ এখানে রয়েছে:

func fieldSet(fields ...string) map[string]bool {
    set := make(map[string]bool, len(fields))
    for _, s := range fields {
        set[s] = true
    }
    return set
}

func (s *SearchResult) SelectFields(fields ...string) map[string]interface{} {
    fs := fieldSet(fields...)
    rt, rv := reflect.TypeOf(*s), reflect.ValueOf(*s)
    out := make(map[string]interface{}, rt.NumField())
    for i := 0; i < rt.NumField(); i++ {
        field := rt.Field(i)
        jsonKey := field.Tag.Get("json")
        if fs[jsonKey] {
            out[jsonKey] = rv.Field(i).Interface()
        }
    }
    return out
}

এবং এখানে একটি চলমান সমাধান যা দেখায় যে আপনি কীভাবে এই পদ্ধতিটিকে কল করবেন এবং আপনার নির্বাচনের মার্শাল করবেন: http://play.golang.org/p/1K9xjQRnO8


এটি ভাবতে আসুন, আপনি যেকোন প্রকার এবং যে কোনও ট্যাগ কীতে সিলেক্টফিল্ড প্যাটার্নটি সাধারণভাবে তৈরি করতে পারেন; এ সম্পর্কিত কিছুই নেই যা অনুসন্ধানের ফলাফল সংজ্ঞা বা জসন কী-এর সাথে সুনির্দিষ্ট।
জোরেলি

আমি প্রতিবিম্ব থেকে দূরে থাকার চেষ্টা করছি তবে এটি প্রকারের তথ্যটি খুব সুন্দরভাবে সংরক্ষণ করে ... আপনার কোডগুলি বৈধ () পদ্ধতিতে যদি / অন্য ট্যাগগুলি একগুচ্ছের চেয়ে আরও ভাল দেখতে লাগে তবে এমন নথির কোড রয়েছে যা যদি আপনি এমনকি একটি আছে)
আকতাউ

7

আমি সবেমাত্র শেরিফ প্রকাশ করেছি , যা স্ট্রাক্ট ক্ষেত্রগুলিতে টীকাযুক্ত ট্যাগের ভিত্তিতে স্ট্র্যাপকে মানচিত্রে রূপান্তর করে। তারপরে আপনি উত্পন্ন মানচিত্রটি মার্শাল (জেএসএন বা অন্যান্য) করতে পারেন। এটি সম্ভবত আপনাকে কলকারীকে অনুরোধ করা ক্ষেত্রগুলির সেটটি কেবল সিরিয়ালাইজ করার অনুমতি দেয় না, তবে আমি কল্পনা করেছি যে গোষ্ঠীর একটি সেট ব্যবহার আপনাকে বেশিরভাগ ক্ষেত্রে কভার করার অনুমতি দেয়। সরাসরি ক্ষেত্রগুলির পরিবর্তে গোষ্ঠীগুলি ব্যবহার করা সম্ভবত ক্যাশে-ক্ষমতা বাড়িয়ে তুলবে।

উদাহরণ:

package main

import (
    "encoding/json"
    "fmt"
    "log"

    "github.com/hashicorp/go-version"
    "github.com/liip/sheriff"
)

type User struct {
    Username string   `json:"username" groups:"api"`
    Email    string   `json:"email" groups:"personal"`
    Name     string   `json:"name" groups:"api"`
    Roles    []string `json:"roles" groups:"api" since:"2"`
}

func main() {
    user := User{
        Username: "alice",
        Email:    "alice@example.org",
        Name:     "Alice",
        Roles:    []string{"user", "admin"},
    }

    v2, err := version.NewVersion("2.0.0")
    if err != nil {
        log.Panic(err)
    }

    o := &sheriff.Options{
        Groups:     []string{"api"},
        ApiVersion: v2,
    }

    data, err := sheriff.Marshal(o, user)
    if err != nil {
        log.Panic(err)
    }

    output, err := json.MarshalIndent(data, "", "  ")
    if err != nil {
        log.Panic(err)
    }
    fmt.Printf("%s", output)
}

7

তিনটি উপাদান নিন:

  1. reflectএকটি struct সব ক্ষেত্র উপর লুপ প্যাকেজ।

  2. ifআপনি যে ক্ষেত্রগুলি চান তা বাছাই করার জন্য একটি বিবৃতি Marshalএবং

  3. encoding/jsonপ্যাকেজ Marshalআপনার পছন্দ অনুসারে ক্ষেত্র।

প্রস্তুতি:

  1. একটি ভাল অনুপাতে তাদের মিশ্রণ। reflect.TypeOf(your_struct).Field(i).Name()এর iদশম ক্ষেত্রের একটি নাম পেতে ব্যবহার করুন your_struct

  2. এর একটি th ক্ষেত্রের reflect.ValueOf(your_struct).Field(i)ধরণের Valueউপস্থাপনা পেতে ব্যবহার করুন ।iyour_struct

  3. ব্যবহারের fieldValue.Interface()এর (টাইপ ইন্টারফেস {} এ upcasted) প্রকৃত মূল্য পুনরুদ্ধার করতে fieldValueধরনের Value(নোট বন্ধনী ব্যবহার - ইন্টারফেস () পদ্ধতি উত্পাদন করেinterface{}

আপনি যদি ভাগ্যক্রমে কোনও ট্রানজিস্টর বা সার্কিট-ব্রেকারগুলিকে প্রক্রিয়াতে না জ্বালিয়ে পরিচালনা করেন তবে আপনার এই জাতীয় কিছু পাওয়া উচিত:

func MarshalOnlyFields(structa interface{},
    includeFields map[string]bool) (jsona []byte, status error) {
    value := reflect.ValueOf(structa)
    typa := reflect.TypeOf(structa)
    size := value.NumField()
    jsona = append(jsona, '{')
    for i := 0; i < size; i++ {
        structValue := value.Field(i)
        var fieldName string = typa.Field(i).Name
        if marshalledField, marshalStatus := json.Marshal((structValue).Interface()); marshalStatus != nil {
            return []byte{}, marshalStatus
        } else {
            if includeFields[fieldName] {
                jsona = append(jsona, '"')
                jsona = append(jsona, []byte(fieldName)...)
                jsona = append(jsona, '"')
                jsona = append(jsona, ':')
                jsona = append(jsona, (marshalledField)...)
                if i+1 != len(includeFields) {
                    jsona = append(jsona, ',')
                }
            }
        }
    }
    jsona = append(jsona, '}')
    return
}

ভজনা:

একটি স্বেচ্ছাসেবী কাঠামো এবং map[string]boolআপনি অন্তর্ভুক্ত করতে চান এমন ক্ষেত্রগুলির সাথে পরিবেশন করুন , উদাহরণস্বরূপ

type magic struct {
    Magic1 int
    Magic2 string
    Magic3 [2]int
}

func main() {
    var magic = magic{0, "tusia", [2]int{0, 1}}
    if json, status := MarshalOnlyFields(magic, map[string]bool{"Magic1": true}); status != nil {
        println("error")
    } else {
        fmt.Println(string(json))
    }

}

বন ক্ষুধা!


সতর্কবাণী! যদি আপনার অন্তর্ভুক্ত ফিল্ডগুলিতে ক্ষেত্রের নাম থাকে, যা প্রকৃত ক্ষেত্রের সাথে মেলে না, আপনি একটি অবৈধ জসন পেতে চলেছেন। তোমাকে সতর্ক করা হইছে.
অ্যাডাম কুরকিউইচ

5

আপনি ট্যাগিং অ্যাট্রিবিউট "অমিটাইফাম্পটি" ব্যবহার করতে পারেন বা fieldsচ্ছিক ক্ষেত্রগুলি পয়েন্টার তৈরি করতে পারেন এবং আপনি যা চান তা বাদ দিতে পারেন।


এটি ওপিএস প্রশ্ন ও ব্যবহারের ক্ষেত্রে সবচেয়ে সঠিক উত্তর।
ব্যবহারকারী 1943442

2
@ ব্যবহারকারী1943442, এটি নয়; ওপি স্পষ্টভাবে উল্লেখ করেছে যে কেন "সর্বশক্তি" প্রয়োগযোগ্য নয়।
ডেভ সি

2

আমিও এই সমস্যার মুখোমুখি হয়েছিলাম, প্রথমে আমি কেবল আমার এইচটিপি হ্যান্ডলারের প্রতিক্রিয়াগুলিকে বিশেষীকরণ করতে চেয়েছিলাম। আমার প্রথম দৃষ্টিভঙ্গি এমন একটি প্যাকেজ তৈরি করছিল যা কোনও স্ট্রাক্টের তথ্যকে অন্য স্ট্রাক্টে অনুলিপি করে এবং তারপরে দ্বিতীয় স্তরের মার্শাল করে। আমি সেই প্যাকেজটি প্রতিবিম্ব ব্যবহার করে করেছি, সুতরাং, কখনও সেই পদ্ধতির পছন্দ হয়নি এবং আমি গতিশীলও ছিলাম না।

সুতরাং আমি এটি করার জন্য এনকোডিং / জেসন প্যাকেজটি পরিবর্তন করার সিদ্ধান্ত নিয়েছি। ফাংশন Marshal, MarshalIndentএবং (Encoder) Encodeঅতিরিক্তভাবে একটি গ্রহণ করে

type F map[string]F

আমি মার্শাল করার জন্য প্রয়োজনীয় ক্ষেত্রগুলির একটি জেএসএন অনুকরণ করতে চেয়েছিলাম, সুতরাং এটি কেবল মানচিত্রে থাকা ক্ষেত্রগুলিকে মার্শাল করে।

https://github.com/JuanTorr/jsont

package main

import (
    "fmt"
    "log"
    "net/http"

    "github.com/JuanTorr/jsont"
)

type SearchResult struct {
    Date        string      `json:"date"`
    IdCompany   int         `json:"idCompany"`
    Company     string      `json:"company"`
    IdIndustry  interface{} `json:"idIndustry"`
    Industry    string      `json:"industry"`
    IdContinent interface{} `json:"idContinent"`
    Continent   string      `json:"continent"`
    IdCountry   interface{} `json:"idCountry"`
    Country     string      `json:"country"`
    IdState     interface{} `json:"idState"`
    State       string      `json:"state"`
    IdCity      interface{} `json:"idCity"`
    City        string      `json:"city"`
} //SearchResult

type SearchResults struct {
    NumberResults int            `json:"numberResults"`
    Results       []SearchResult `json:"results"`
} //type SearchResults
func main() {
    msg := SearchResults{
        NumberResults: 2,
        Results: []SearchResult{
            {
                Date:        "12-12-12",
                IdCompany:   1,
                Company:     "alfa",
                IdIndustry:  1,
                Industry:    "IT",
                IdContinent: 1,
                Continent:   "america",
                IdCountry:   1,
                Country:     "México",
                IdState:     1,
                State:       "CDMX",
                IdCity:      1,
                City:        "Atz",
            },
            {
                Date:        "12-12-12",
                IdCompany:   2,
                Company:     "beta",
                IdIndustry:  1,
                Industry:    "IT",
                IdContinent: 1,
                Continent:   "america",
                IdCountry:   2,
                Country:     "USA",
                IdState:     2,
                State:       "TX",
                IdCity:      2,
                City:        "XYZ",
            },
        },
    }
    fmt.Println(msg)
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {

        //{"numberResults":2,"results":[{"date":"12-12-12","idCompany":1,"idIndustry":1,"country":"México"},{"date":"12-12-12","idCompany":2,"idIndustry":1,"country":"USA"}]}
        err := jsont.NewEncoder(w).Encode(msg, jsont.F{
            "numberResults": nil,
            "results": jsont.F{
                "date":       nil,
                "idCompany":  nil,
                "idIndustry": nil,
                "country":    nil,
            },
        })
        if err != nil {
            log.Fatal(err)
        }
    })

    http.ListenAndServe(":3009", nil)
}

আমি এখনও চেষ্টা করে দেখিনি, তবে এটি দুর্দান্ত দেখাচ্ছে। এটি আরও ভাল হবে যদি মার্শেলার ইন্টারফেসটি পাশাপাশি সমর্থন করে।
হুগি

1

প্রশ্নটি এখন কিছুটা পুরানো, তবে আমি কিছুক্ষণ আগে একই সমস্যাটি নিয়ে এসেছি এবং এটি করার সহজ কোনও উপায় আমি খুঁজে না পাওয়ায় আমি এই উদ্দেশ্যটি পূরণ করে একটি লাইব্রেরি তৈরি করেছি। এটি map[string]interface{}স্ট্যাটিক স্ট্রাক্ট থেকে সহজেই জেনারেট করতে দেয় ।

https://github.com/tuvistavie/structomap


আপনি এখন আমার রেসিপি থেকে কোড স্নিপেট ব্যবহার করে সহজেই এটি করতে পারেন।
অ্যাডাম কুরকিউইচ

স্নিপেট গ্রন্থাগারের একটি সাবসেট, তবে এখানে ফিরে আসার একটি বড় বিষয় []byteএটি খুব পুনরায় ব্যবহারযোগ্য নয়: এর পরে কোনও ক্ষেত্র যুক্ত করার কোনও সহজ উপায় নেই। সুতরাং আমি একটি তৈরি করার পরামর্শ দিয়েছি map[string]interface{}এবং JSON সিরিয়ালকরণ অংশটি স্ট্যান্ডার্ড লাইব্রেরিতে ছেড়ে দেই।
ড্যানিয়েল পেরেজ

1

আমার একই সমস্যা তবে একই রকম ছিল না। নীচের কোডটি আপনার সমস্যাটিকেও সমাধান করে, অবশ্যই যদি আপনি পারফরম্যান্সের সমস্যাটি মনে করেন না। আপনার সিস্টেমে এই জাতীয় সমাধানটি প্রয়োগ করার আগে আমি আপনাকে পরামর্শ দিচ্ছি যদি আপনি পারেন তবে আপনার কাঠামোগুলি পুনরায় ডিজাইন করতে। পরিবর্তনশীল কাঠামোর প্রতিক্রিয়া প্রেরণ করা ওভার ইঞ্জিনিয়ারিং। আমি বিশ্বাস করি একটি প্রতিক্রিয়া কাঠামো একটি অনুরোধ এবং সংস্থানগুলির মধ্যে একটি চুক্তির প্রতিনিধিত্ব করে এবং এটি নির্ভর অনুরোধ হওয়া উচিত নয় ( কিছু ক্ষেত্রে আমাদের এই নকশাটি বাস্তবায়ন করতে হবে, আপনি যদি বিশ্বাস করেন যে আপনি সেই ক্ষেত্রে রয়েছেন তবে আমি এখানে প্লে লিঙ্ক এবং কোডটি ব্যবহার করি।

type User2 struct {
    ID       int    `groups:"id" json:"id,omitempty"`
    Username string `groups:"username" json:"username,omitempty"`
    Nickname string `groups:"nickname" json:"nickname,omitempty"`
}

type User struct {
    ID       int    `groups:"private,public" json:"id,omitempty"`
    Username string `groups:"private" json:"username,omitempty"`
    Nickname string `groups:"public" json:"nickname,omitempty"`
}

var (
    tagName = "groups"
)

//OmitFields sets fields nil by checking their tag group value and access control tags(acTags)
func OmitFields(obj interface{}, acTags []string) {
    //nilV := reflect.Value{}
    sv := reflect.ValueOf(obj).Elem()
    st := sv.Type()
    if sv.Kind() == reflect.Struct {
        for i := 0; i < st.NumField(); i++ {
            fieldVal := sv.Field(i)
            if fieldVal.CanSet() {
                tagStr := st.Field(i).Tag.Get(tagName)
                if len(tagStr) == 0 {
                    continue
                }
                tagList := strings.Split(strings.Replace(tagStr, " ", "", -1), ",")
                //fmt.Println(tagList)
                // ContainsCommonItem checks whether there is at least one common item in arrays
                if !ContainsCommonItem(tagList, acTags) {
                    fieldVal.Set(reflect.Zero(fieldVal.Type()))
                }
            }
        }
    }
}

//ContainsCommonItem checks if arrays have at least one equal item
func ContainsCommonItem(arr1 []string, arr2 []string) bool {
    for i := 0; i < len(arr1); i++ {
        for j := 0; j < len(arr2); j++ {
            if arr1[i] == arr2[j] {
                return true
            }
        }
    }
    return false
}
func main() {
    u := User{ID: 1, Username: "very secret", Nickname: "hinzir"}
    //assume authenticated user doesn't has permission to access private fields
    OmitFields(&u, []string{"public"}) 
    bytes, _ := json.Marshal(&u)
    fmt.Println(string(bytes))


    u2 := User2{ID: 1, Username: "very secret", Nickname: "hinzir"}
    //you want to filter fields by field names
    OmitFields(&u2, []string{"id", "nickname"}) 
    bytes, _ = json.Marshal(&u2)
    fmt.Println(string(bytes))

}

1

কিছু ক্ষেত্র উপেক্ষা করে স্ট্রাক্টটিকে JSON স্ট্রিংয়ে রূপান্তর করতে আমি এই ফাংশনটি তৈরি করেছি। আশা করি এটি সাহায্য করবে।

func GetJSONString(obj interface{}, ignoreFields ...string) (string, error) {
    toJson, err := json.Marshal(obj)
    if err != nil {
        return "", err
    }

    if len(ignoreFields) == 0 {
        return string(toJson), nil
    }

    toMap := map[string]interface{}{}
    json.Unmarshal([]byte(string(toJson)), &toMap)

    for _, field := range ignoreFields {
        delete(toMap, field)
    }

    toJson, err = json.Marshal(toMap)
    if err != nil {
        return "", err
    }
    return string(toJson), nil
}

উদাহরণ: https://play.golang.org/p/nmq7MFF47Gp

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.