Просто объявите свой тип вне функций:
type entity struct {
Id string `json:"id"`
Properties map[string]string `json:"properties"`
Type string `json:"type"`
}
И повторно используйте его в handleEntityProperties()
и в подписи sendData()
:
func handleEntityProperties(w http.ResponseWriter, r *http.Request) {
const sliceSize = 100
var entityProperties struct {
Instance string `json:"instance"`
Entities []entity `json:"entities"`
}
body, err := ioutil.ReadAll(r.Body)
if err != nil {
panic(err)
}
if !json.Valid([]byte(body)) {
fmt.Fprintf(w, "invalid json")
return
}
err = json.Unmarshal(body, &entityProperties)
sendData(entityProperties.Entities[0:sliceSize])
return
}
func sendData(entities []entity) {
log.Println("Doing things with entities ", entities)
}
Также обратите внимание, что есть нет никакой гарантии, что клиент отправит не менее 100 сущностей, поэтому вам следует убедиться, что в противном случае выражение среза может привести к пани времени выполнения c:
max := 100
if len(entityProperties.Entities) < max {
max = len(entityProperties.Entities)
}
sendData(entityProperties.Entities[:max])
Также эта проверка на недопустимость JSON не нужно: если JSON недопустимо, json.Unmarshal()
сообщит (не nil
) об ошибке, и вы об этом узнаете.
Продвигаясь дальше, вы не будете даже если вам нужно прочитать полное тело в память (в байтовый фрагмент), вы можете использовать json.Decoder
для непосредственного чтения из него (без промежуточного буфера памяти), например:
dec := json.NewDecoder(r.Body)
if err := dec.Decode(&entityProperties); err != nil {
// handle error
}
И последнее утверждение return
также не нужно.
Так что улучшенная версия может выглядеть так:
func handleEntityProperties(w http.ResponseWriter, r *http.Request) {
var entityProperties struct {
Instance string `json:"instance"`
Entities []entity `json:"entities"`
}
dec := json.NewDecoder(r.Body)
if err := dec.Decode(&entityProperties); err != nil {
// handle error
http.Error(w, "invalid json", http.StatusBadRequest)
return
}
max := 100
if len(entityProperties.Entities) < max {
max = len(entityProperties.Entities)
}
sendData(entityProperties.Entities[:max])
}