Skip to content

Commit d7284fe

Browse files
committed
refactor: nest reaction resource names under memos
1 parent c2aea5a commit d7284fe

File tree

8 files changed

+63
-53
lines changed

8 files changed

+63
-53
lines changed

proto/api/v1/memo_service.proto

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ service MemoService {
100100
}
101101
// DeleteMemoReaction deletes a reaction for a memo.
102102
rpc DeleteMemoReaction(DeleteMemoReactionRequest) returns (google.protobuf.Empty) {
103-
option (google.api.http) = {delete: "/api/v1/{name=reactions/*}"};
103+
option (google.api.http) = {delete: "/api/v1/{name=memos/*/reactions/*}"};
104104
option (google.api.method_signature) = "name";
105105
}
106106
}
@@ -115,14 +115,14 @@ enum Visibility {
115115
message Reaction {
116116
option (google.api.resource) = {
117117
type: "memos.api.v1/Reaction"
118-
pattern: "reactions/{reaction}"
118+
pattern: "memos/{memo}/reactions/{reaction}"
119119
name_field: "name"
120120
singular: "reaction"
121121
plural: "reactions"
122122
};
123123

124124
// The resource name of the reaction.
125-
// Format: reactions/{reaction}
125+
// Format: memos/{memo}/reactions/{reaction}
126126
string name = 1 [
127127
(google.api.field_behavior) = OUTPUT_ONLY,
128128
(google.api.field_behavior) = IDENTIFIER
@@ -501,7 +501,7 @@ message UpsertMemoReactionRequest {
501501

502502
message DeleteMemoReactionRequest {
503503
// Required. The resource name of the reaction to delete.
504-
// Format: reactions/{reaction}
504+
// Format: memos/{memo}/reactions/{reaction}
505505
string name = 1 [
506506
(google.api.field_behavior) = REQUIRED,
507507
(google.api.resource_reference) = {type: "memos.api.v1/Reaction"}

proto/gen/api/v1/memo_service.pb.go

Lines changed: 8 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

proto/gen/api/v1/memo_service.pb.gw.go

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

proto/gen/openapi.yaml

Lines changed: 30 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -960,6 +960,35 @@ paths:
960960
application/json:
961961
schema:
962962
$ref: '#/components/schemas/Status'
963+
/api/v1/memos/{memo}/reactions/{reaction}:
964+
delete:
965+
tags:
966+
- MemoService
967+
description: DeleteMemoReaction deletes a reaction for a memo.
968+
operationId: MemoService_DeleteMemoReaction
969+
parameters:
970+
- name: memo
971+
in: path
972+
description: The memo id.
973+
required: true
974+
schema:
975+
type: string
976+
- name: reaction
977+
in: path
978+
description: The reaction id.
979+
required: true
980+
schema:
981+
type: string
982+
responses:
983+
"200":
984+
description: OK
985+
content: {}
986+
default:
987+
description: Default error response
988+
content:
989+
application/json:
990+
schema:
991+
$ref: '#/components/schemas/Status'
963992
/api/v1/memos/{memo}/relations:
964993
get:
965994
tags:
@@ -1025,29 +1054,6 @@ paths:
10251054
application/json:
10261055
schema:
10271056
$ref: '#/components/schemas/Status'
1028-
/api/v1/reactions/{reaction}:
1029-
delete:
1030-
tags:
1031-
- MemoService
1032-
description: DeleteMemoReaction deletes a reaction for a memo.
1033-
operationId: MemoService_DeleteMemoReaction
1034-
parameters:
1035-
- name: reaction
1036-
in: path
1037-
description: The reaction id.
1038-
required: true
1039-
schema:
1040-
type: string
1041-
responses:
1042-
"200":
1043-
description: OK
1044-
content: {}
1045-
default:
1046-
description: Default error response
1047-
content:
1048-
application/json:
1049-
schema:
1050-
$ref: '#/components/schemas/Status'
10511057
/api/v1/users:
10521058
get:
10531059
tags:
@@ -2640,7 +2646,7 @@ components:
26402646
type: string
26412647
description: |-
26422648
The resource name of the reaction.
2643-
Format: reactions/{reaction}
2649+
Format: memos/{memo}/reactions/{reaction}
26442650
creator:
26452651
readOnly: true
26462652
type: string

server/router/api/v1/reaction_service.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ func (s *APIV1Service) DeleteMemoReaction(ctx context.Context, request *v1pb.Del
6363
return nil, status.Errorf(codes.Unauthenticated, "user not authenticated")
6464
}
6565

66-
reactionID, err := ExtractReactionIDFromName(request.Name)
66+
_, reactionID, err := ExtractMemoReactionIDFromName(request.Name)
6767
if err != nil {
6868
return nil, status.Errorf(codes.InvalidArgument, "invalid reaction name: %v", err)
6969
}
@@ -95,8 +95,10 @@ func (s *APIV1Service) DeleteMemoReaction(ctx context.Context, request *v1pb.Del
9595

9696
func convertReactionFromStore(reaction *store.Reaction) *v1pb.Reaction {
9797
reactionUID := fmt.Sprintf("%d", reaction.ID)
98+
// Generate nested resource name: memos/{memo}/reactions/{reaction}
99+
// reaction.ContentID already contains "memos/{memo}"
98100
return &v1pb.Reaction{
99-
Name: fmt.Sprintf("%s%s", ReactionNamePrefix, reactionUID),
101+
Name: fmt.Sprintf("%s/%s%s", reaction.ContentID, ReactionNamePrefix, reactionUID),
100102
Creator: fmt.Sprintf("%s%d", UserNamePrefix, reaction.CreatorID),
101103
ContentId: reaction.ContentID,
102104
ReactionType: reaction.ReactionType,

server/router/api/v1/resource_name.go

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -105,18 +105,19 @@ func ExtractAttachmentUIDFromName(name string) (string, error) {
105105
return id, nil
106106
}
107107

108-
// ExtractReactionIDFromName returns the reaction ID from a resource name.
109-
// e.g., "reactions/123" -> 123.
110-
func ExtractReactionIDFromName(name string) (int32, error) {
111-
tokens, err := GetNameParentTokens(name, ReactionNamePrefix)
108+
// ExtractMemoReactionIDFromName returns the memo UID and reaction ID from a resource name.
109+
// e.g., "memos/abc/reactions/123" -> ("abc", 123).
110+
func ExtractMemoReactionIDFromName(name string) (string, int32, error) {
111+
tokens, err := GetNameParentTokens(name, MemoNamePrefix, ReactionNamePrefix)
112112
if err != nil {
113-
return 0, err
113+
return "", 0, err
114114
}
115-
id, err := util.ConvertStringToInt32(tokens[0])
115+
memoUID := tokens[0]
116+
reactionID, err := util.ConvertStringToInt32(tokens[1])
116117
if err != nil {
117-
return 0, errors.Errorf("invalid reaction ID %q", tokens[0])
118+
return "", 0, errors.Errorf("invalid reaction ID %q", tokens[1])
118119
}
119-
return id, nil
120+
return memoUID, reactionID, nil
120121
}
121122

122123
// ExtractInboxIDFromName returns the inbox ID from a resource name.

server/router/api/v1/test/reaction_service_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,8 +183,9 @@ func TestDeleteMemoReaction(t *testing.T) {
183183

184184
// Try to delete non-existent reaction - should fail with permission denied
185185
// (not "not found" to avoid information disclosure)
186+
// Use new nested resource format: memos/{memo}/reactions/{reaction}
186187
_, err = ts.Service.DeleteMemoReaction(userCtx, &apiv1.DeleteMemoReactionRequest{
187-
Name: "reactions/99999",
188+
Name: "memos/nonexistent/reactions/99999",
188189
})
189190
require.Error(t, err)
190191
require.Contains(t, err.Error(), "permission denied")

0 commit comments

Comments
 (0)