Case
For example, there is a GET interface that can obtain user information in batches👇
> curl 'http://localhost:8080/user/1,2,3' [ { "user_id":1, "other_suff":... }, { "user_id":2, "other_suff":... }, { "user_id":3, "other_suff":... } ]
At the same time, we must put user information and some of their order information together and assemble it into an interface for 👇 to meet other business needs.
[ { "user_info":{ "user_id":1, "other_suff":... }, "order_info":{ "order_id":1, "user_id":1, "other_suff":... } }, { "user_info":{ "user_id":2, "other_suff":... }, "order_info":{ "order_id":2, "user_id":2, "other_suff":... } }, { "user_info":{ "user_id":3, "other_suff":... }, "order_info":{ "order_id":3, "user_id":3, "other_suff":... } } ]
analyze
It is very simple to solve this problem: use tools to parse the json of user information and order information to obtain the structure, then call their interface to obtain the data, associate and assemble according to the id, and finally return.
One problem with this approach is that the code parses the complete structure of user and order. If the user information returned by the user interface has added fields, the structure we here needs to be updated synchronously, otherwise the data we give will be incomplete. (This may be very painful. If you ask other teams to add fields, you have to schedule...)
In fact, as the "middleman" of data, we only care about user_id in the user interface json. We use this field to associate order data. We don't care about other_suff or other data in the user information, just ensure that it is completely transmitted.
according to/pkg/encoding/json/#Unmarshal, we can know that we can directly throw a map[string]interface{} to , which can also be parsed normally, so we can write a more general transparent code.
type Content []map[string]interface{} func (c Content) GetByFieldName(name string, defaultVal interface{}) infterface{} { for _, item := range c { val, ok := item[name] if !ok { continue } if val == nil { return defaultVal } return val } return defaultVal } func getUserContentByIDs(ids []int) Content { ... var c Content err := (jsonData, &c) ... return c } func getOrderContentByUserIDs(ids []int) Content {.../*Same as above*/} func Handler(userIDs []int) []Combine { users := getUserContentByIDs(userIDs) orders := getOrderContentByUserIDs(userIDs) // Here it is assumed that the user and the order are one-to-one relationship ret := make([]Combine, 0, len(users)) for _, u := range users { for _, o := range orders { userID := ("user_id", 0) orderUserID := ("user_id", 0) if userID != 0 && userID == orderUserID { ret = append(ret, Combine{ UserInfo: u, OrderInfo: o, }) break } } } return ret }
. In the above example, each query of Content is to iterate over the array. If the data volume is large or the query is frequent, you can encapsulate a map according to the item's unique label when initializing the Content to improve query efficiency.
The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.