examples/profilesvc: fix PUT and PATCH semantics
Peter Bourgon
8 years ago
55 | 55 | s.mtx.Lock() |
56 | 56 | defer s.mtx.Unlock() |
57 | 57 | if _, ok := s.m[p.ID]; ok { |
58 | return errAlreadyExists | |
58 | return errAlreadyExists // POST = create, don't overwrite | |
59 | 59 | } |
60 | 60 | s.m[p.ID] = p |
61 | 61 | return nil |
77 | 77 | } |
78 | 78 | s.mtx.Lock() |
79 | 79 | defer s.mtx.Unlock() |
80 | if _, ok := s.m[id]; ok { | |
81 | return errAlreadyExists | |
82 | } | |
83 | s.m[id] = p | |
80 | s.m[id] = p // PUT = create or update | |
84 | 81 | return nil |
85 | 82 | } |
86 | 83 | |
87 | 84 | func (s *inmemService) PatchProfile(ctx context.Context, id string, p Profile) error { |
88 | return s.PutProfile(ctx, id, p) // perhaps more granular behavior is needed here | |
85 | if p.ID != "" && id != p.ID { | |
86 | return errInconsistentIDs | |
87 | } | |
88 | ||
89 | s.mtx.Lock() | |
90 | defer s.mtx.Unlock() | |
91 | ||
92 | existing, ok := s.m[id] | |
93 | if !ok { | |
94 | return errNotFound // PATCH = update existing, don't create | |
95 | } | |
96 | ||
97 | // We assume that it's not possible to PATCH the ID, and that it's not | |
98 | // possible to PATCH any field to its zero value. That is, the zero value | |
99 | // means not specified. The way around this is to use e.g. Name *string in | |
100 | // the Profile definition. But since this is just a demonstrative example, | |
101 | // I'm leaving that out. | |
102 | ||
103 | if p.Name != "" { | |
104 | existing.Name = p.Name | |
105 | } | |
106 | if len(p.Addresses) > 0 { | |
107 | existing.Addresses = p.Addresses | |
108 | } | |
109 | s.m[id] = existing | |
110 | return nil | |
89 | 111 | } |
90 | 112 | |
91 | 113 | func (s *inmemService) DeleteProfile(ctx context.Context, id string) error { |