func (s *Service) Create(m kit.Model, user kit.User) apperror.Error { res := s.resources[m.Collection()] if res == nil { return &apperror.Err{ Code: "unknown_resource", Message: fmt.Sprintf("The resource %v was not registered with service", m.Collection()), } } return res.Create(m, user) }
// SerializeModel converts a model into the target format. func (s *Serializer) SerializeModel(model kit.Model) (interface{}, []interface{}, apperror.Error) { // Find backend. backend := s.findBackend(model.Collection()) if backend == nil { return nil, nil, apperror.New("unknown_collection", fmt.Sprintf("Can't serialize model of unknown collection %v", model.Collection())) } // Serialize model. m, extra, err := SerializeModel(backend, model) if err != nil { return nil, nil, err } // Convert extra slice to interface slice. var rawExtra []interface{} for _, item := range extra { rawExtra = append(rawExtra, item) } return m, rawExtra, nil }
func SerializeModel(backend db.Backend, m kit.Model) (*ApiModel, []*ApiModel, apperror.Error) { modelData, err := backend.ModelToMap(m, true, false) if err != nil { return nil, nil, apperror.Wrap(err, "model_convert_error", "") } info := backend.ModelInfo(m.Collection()) data := &ApiModel{ Type: m.Collection(), Id: m.GetStrId(), Attributes: modelData, } // Build relationship data. includedModels := make([]*ApiModel, 0) // Check every model field. r := reflector.R(m).MustStruct() for fieldName, rel := range info.Relations() { // Retrieve the related model. field := r.Field(fieldName) if field != nil { return nil, nil, apperror.Wrap(err, "model_get_field_error") } // If field is zero value, skip. if field.IsZero() { continue } related := make([]kit.Model, 0) if !rel.IsMany() { // Make sure that we have a pointer. if !field.IsPtr() { field = field.Addr() } related = append(related, field.Interface().(kit.Model)) } else { slice := field.MustSlice() for _, item := range slice.Items() { if !item.IsPtr() { item = item.Addr() } related = append(related, item.Interface().(kit.Model)) } } for _, relatedModel := range related { // Convert the related model. relationData, included, err := SerializeModel(backend, relatedModel) if err != nil { return nil, nil, apperror.Wrap(err, "included_model_serialize_error", "") } // Build relation info and set in in relationships map. relation := &ApiModel{ Type: relatedModel.Collection(), Id: relatedModel.GetStrId(), } isSingle := !rel.IsMany() data.AddRelation(rel.MarshalName(), relation, isSingle) // Add related model to included data. includedModels = append(includedModels, relationData) // Add nested included models to included data. includedModels = append(includedModels, included...) } } return data, includedModels, nil }