Skip to content

Commit e6b5c89

Browse files
committed
refactor(api,openapi): simplify tag endpoints
Add new tag endpoints that infer namespace from authentication context: - GET/POST /api/tags - PATCH/DELETE /api/tags/{name} - POST/DELETE /api/devices/{uid}/tags/{name} Mark legacy endpoints with tenant path parameter as deprecated.
1 parent de553b7 commit e6b5c89

10 files changed

Lines changed: 279 additions & 14 deletions

api/routes/routes.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,14 @@ func NewRouter(service services.Service, opts ...Option) *echo.Echo {
151151
publicAPI.POST(URLPushTagToDevice, gateway.Handler(handler.PushTagToDevice), routesmiddleware.RequiresPermission(authorizer.TagCreate))
152152
publicAPI.DELETE(URLPullTagFromDevice, gateway.Handler(handler.PullTagFromDevice), routesmiddleware.RequiresPermission(authorizer.TagDelete))
153153

154+
// NOTE: Legacy tag routes with tenant in path for backward compatibility.
155+
publicAPI.GET(URLOldGetTags, gateway.Handler(handler.GetTags))
156+
publicAPI.POST(URLOldCreateTag, gateway.Handler(handler.CreateTag), routesmiddleware.RequiresPermission(authorizer.TagCreate))
157+
publicAPI.PATCH(URLOldUpdateTag, gateway.Handler(handler.UpdateTag), routesmiddleware.RequiresPermission(authorizer.TagUpdate))
158+
publicAPI.DELETE(URLOldDeleteTag, gateway.Handler(handler.DeleteTag), routesmiddleware.RequiresPermission(authorizer.TagDelete))
159+
publicAPI.POST(URLOldPushTagToDevice, gateway.Handler(handler.PushTagToDevice), routesmiddleware.RequiresPermission(authorizer.TagCreate))
160+
publicAPI.DELETE(URLOldPullTagFromDevice, gateway.Handler(handler.PullTagFromDevice), routesmiddleware.RequiresPermission(authorizer.TagDelete))
161+
154162
publicAPI.GET(GetSessionsURL, routesmiddleware.Authorize(gateway.Handler(handler.GetSessionList)))
155163
publicAPI.GET(GetSessionURL, routesmiddleware.Authorize(gateway.Handler(handler.GetSession)))
156164

api/routes/tags.go

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,19 @@ import (
1010
)
1111

1212
const (
13-
URLGetTags = "/namespaces/:tenant/tags"
14-
URLCreateTag = "/namespaces/:tenant/tags"
15-
URLUpdateTag = "/namespaces/:tenant/tags/:name"
16-
URLDeleteTag = "/namespaces/:tenant/tags/:name"
17-
URLPushTagToDevice = "/namespaces/:tenant/devices/:uid/tags/:name"
18-
URLPullTagFromDevice = "/namespaces/:tenant/devices/:uid/tags/:name"
13+
URLGetTags = "/tags"
14+
URLCreateTag = "/tags"
15+
URLUpdateTag = "/tags/:name"
16+
URLDeleteTag = "/tags/:name"
17+
URLPushTagToDevice = "/devices/:uid/tags/:name"
18+
URLPullTagFromDevice = "/devices/:uid/tags/:name"
19+
20+
URLOldGetTags = "/namespaces/:tenant/tags"
21+
URLOldCreateTag = "/namespaces/:tenant/tags"
22+
URLOldUpdateTag = "/namespaces/:tenant/tags/:name"
23+
URLOldDeleteTag = "/namespaces/:tenant/tags/:name"
24+
URLOldPushTagToDevice = "/namespaces/:tenant/devices/:uid/tags/:name"
25+
URLOldPullTagFromDevice = "/namespaces/:tenant/devices/:uid/tags/:name"
1926
)
2027

2128
func (h *Handler) CreateTag(c gateway.Context) error {

openapi/spec/community-openapi.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,12 @@ paths:
111111
$ref: paths/api@namespaces@api-key.yaml
112112
/api/namespaces/api-key/{key}:
113113
$ref: paths/api@namespaces@api-key@{key}.yaml
114+
/api/tags:
115+
$ref: paths/api@tags.yaml
116+
/api/tags/{name}:
117+
$ref: paths/api@tags@{name}.yaml
118+
/api/devices/{uid}/tags/{name}:
119+
$ref: paths/api@devices@{uid}@tags@{name}.yaml
114120
/api/namespaces/{tenant}/tags:
115121
$ref: paths/api@namespaces@{tenant}@tags.yaml
116122
/api/namespaces/{tenant}/tags/{name}:

openapi/spec/openapi.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,12 @@ paths:
151151
$ref: paths/api@namespaces@api-key.yaml
152152
/api/namespaces/api-key/{key}:
153153
$ref: paths/api@namespaces@api-key@{key}.yaml
154+
/api/tags:
155+
$ref: paths/api@tags.yaml
156+
/api/tags/{name}:
157+
$ref: paths/api@tags@{name}.yaml
158+
/api/devices/{uid}/tags/{name}:
159+
$ref: paths/api@devices@{uid}@tags@{name}.yaml
154160
/api/namespaces/{tenant}/tags:
155161
$ref: paths/api@namespaces@{tenant}@tags.yaml
156162
/api/namespaces/{tenant}/tags/{name}:
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
post:
2+
operationId: pushTagToDevice
3+
summary: Associate a tag with a device
4+
description: Associates a tag with a device in the authenticated namespace.
5+
tags:
6+
- community
7+
- tags
8+
security:
9+
- jwt: []
10+
- api-key: []
11+
parameters:
12+
- $ref: ../components/parameters/path/deviceUIDPath.yaml
13+
- name: name
14+
description: Tag name to associate
15+
schema:
16+
type: string
17+
pattern: ^[a-zA-Z0-9-_]+$
18+
example: prod
19+
required: true
20+
in: path
21+
responses:
22+
'204':
23+
description: Tag successfully associated with device
24+
'400':
25+
$ref: ../components/responses/400.yaml
26+
'401':
27+
$ref: ../components/responses/401.yaml
28+
'403':
29+
$ref: ../components/responses/403.yaml
30+
'404':
31+
$ref: ../components/responses/404.yaml
32+
'500':
33+
$ref: ../components/responses/500.yaml
34+
delete:
35+
operationId: pullTagFromDevice
36+
summary: Remove a tag from a device
37+
description: Removes a tag from a device in the authenticated namespace.
38+
tags:
39+
- community
40+
- tags
41+
security:
42+
- jwt: []
43+
- api-key: []
44+
parameters:
45+
- $ref: ../components/parameters/path/deviceUIDPath.yaml
46+
- name: name
47+
description: Tag name to remove
48+
schema:
49+
type: string
50+
pattern: ^[a-zA-Z0-9-_]+$
51+
example: prod
52+
required: true
53+
in: path
54+
responses:
55+
'204':
56+
description: Tag successfully removed from device
57+
'400':
58+
$ref: ../components/responses/400.yaml
59+
'401':
60+
$ref: ../components/responses/401.yaml
61+
'403':
62+
$ref: ../components/responses/403.yaml
63+
'404':
64+
$ref: ../components/responses/404.yaml
65+
'500':
66+
$ref: ../components/responses/500.yaml

openapi/spec/paths/api@namespaces@{tenant}@devices@{uid}@tags@{name}.yaml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
post:
2-
operationId: pushTagToDevice
2+
operationId: pushTagToDeviceDeprecated
3+
deprecated: true
34
summary: Associate a tag with a device
5+
description: '**Deprecated**: Use `POST /api/devices/{uid}/tags/{name}` instead.'
46
tags:
57
- community
68
- tags
@@ -32,8 +34,10 @@ post:
3234
'500':
3335
$ref: ../components/responses/500.yaml
3436
delete:
35-
operationId: pullTagFromDevice
37+
operationId: pullTagFromDeviceDeprecated
38+
deprecated: true
3639
summary: Remove a tag from a device
40+
description: '**Deprecated**: Use `DELETE /api/devices/{uid}/tags/{name}` instead.'
3741
tags:
3842
- community
3943
- tags

openapi/spec/paths/api@namespaces@{tenant}@tags.yaml

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
get:
2-
operationId: getTags
2+
operationId: getTagsDeprecated
3+
deprecated: true
34
summary: Retrieve all tags associated with a namespace
5+
description: '**Deprecated**: Use `GET /api/tags` instead.'
46
tags:
57
- community
68
- tags
@@ -36,9 +38,10 @@ get:
3638
'500':
3739
$ref: ../components/responses/500.yaml
3840
post:
39-
operationId: createTag
41+
operationId: createTagDeprecated
42+
deprecated: true
4043
summary: Create a new tag in the namespace
41-
description: Creates a tag that can be later associated with content. Tag names must be unique within the namespace.
44+
description: '**Deprecated**: Use `POST /api/tags` instead. Creates a tag that can be later associated with content. Tag names must be unique within the namespace.'
4245
tags:
4346
- community
4447
- tags

openapi/spec/paths/api@namespaces@{tenant}@tags@{name}.yaml

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
patch:
2-
operationId: updateTag
2+
operationId: updateTagDeprecated
3+
deprecated: true
34
summary: Update a tag
5+
description: '**Deprecated**: Use `PATCH /api/tags/{name}` instead.'
46
tags:
57
- community
68
- tags
@@ -53,9 +55,10 @@ patch:
5355
'500':
5456
$ref: ../components/responses/500.yaml
5557
delete:
56-
operationId: deleteTag
58+
operationId: deleteTagDeprecated
59+
deprecated: true
5760
summary: Delete a tag
58-
description: Removes a tag and all its associations
61+
description: '**Deprecated**: Use `DELETE /api/tags/{name}` instead. Removes a tag and all its associations.'
5962
tags:
6063
- community
6164
- tags

openapi/spec/paths/api@tags.yaml

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
get:
2+
operationId: getTags
3+
summary: Retrieve all tags associated with the namespace
4+
description: Retrieves all tags for the authenticated namespace.
5+
tags:
6+
- community
7+
- tags
8+
security:
9+
- jwt: []
10+
- api-key: []
11+
parameters:
12+
- $ref: ../components/parameters/query/filterQuery.yaml
13+
- $ref: ../components/parameters/query/pageQuery.yaml
14+
- $ref: ../components/parameters/query/perPageQuery.yaml
15+
responses:
16+
'200':
17+
description: Success to get tag list.
18+
headers:
19+
X-Total-Count:
20+
description: Tags' total number.
21+
schema:
22+
type: string
23+
minimum: 0
24+
content:
25+
application/json:
26+
schema:
27+
type: array
28+
items:
29+
$ref: ../components/schemas/tag.yaml
30+
'401':
31+
$ref: ../components/responses/401.yaml
32+
'403':
33+
$ref: ../components/responses/403.yaml
34+
'404':
35+
$ref: ../components/responses/404.yaml
36+
'500':
37+
$ref: ../components/responses/500.yaml
38+
post:
39+
operationId: createTag
40+
summary: Create a new tag in the namespace
41+
description: Creates a tag in the authenticated namespace that can be later associated with content. Tag names must be unique within the namespace.
42+
tags:
43+
- community
44+
- tags
45+
security:
46+
- jwt: []
47+
- api-key: []
48+
requestBody:
49+
required: true
50+
content:
51+
application/json:
52+
schema:
53+
type: object
54+
required:
55+
- name
56+
properties:
57+
name:
58+
type: string
59+
minLength: 3
60+
maxLength: 255
61+
example: dev
62+
responses:
63+
'201':
64+
description: Tag successfully created
65+
'400':
66+
$ref: ../components/responses/400.yaml
67+
'401':
68+
$ref: ../components/responses/401.yaml
69+
'403':
70+
$ref: ../components/responses/403.yaml
71+
'404':
72+
$ref: ../components/responses/404.yaml
73+
'409':
74+
$ref: ../components/responses/409.yaml
75+
'500':
76+
$ref: ../components/responses/500.yaml
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
patch:
2+
operationId: updateTag
3+
summary: Update a tag
4+
description: Updates a tag in the authenticated namespace.
5+
tags:
6+
- community
7+
- tags
8+
security:
9+
- jwt: []
10+
- api-key: []
11+
parameters:
12+
- name: name
13+
description: Current tag name
14+
schema:
15+
type: string
16+
pattern: ^[a-zA-Z0-9-_]+$
17+
example: prod
18+
required: true
19+
in: path
20+
requestBody:
21+
required: true
22+
content:
23+
application/json:
24+
schema:
25+
type: object
26+
required:
27+
- name
28+
properties:
29+
name:
30+
type: string
31+
minLength: 3
32+
maxLength: 255
33+
pattern: ^[a-zA-Z0-9-_]+$
34+
example: dev
35+
description: New tag name
36+
responses:
37+
'200':
38+
description: Tag successfully updated
39+
content:
40+
application/json:
41+
schema:
42+
$ref: ../components/schemas/tag.yaml
43+
'400':
44+
$ref: ../components/responses/400.yaml
45+
'401':
46+
$ref: ../components/responses/401.yaml
47+
'403':
48+
$ref: ../components/responses/403.yaml
49+
'404':
50+
$ref: ../components/responses/404.yaml
51+
'409':
52+
$ref: ../components/responses/409.yaml
53+
'500':
54+
$ref: ../components/responses/500.yaml
55+
delete:
56+
operationId: deleteTag
57+
summary: Delete a tag
58+
description: Removes a tag and all its associations from the authenticated namespace.
59+
tags:
60+
- community
61+
- tags
62+
security:
63+
- jwt: []
64+
- api-key: []
65+
parameters:
66+
- name: name
67+
description: Tag name to delete
68+
schema:
69+
type: string
70+
pattern: ^[a-zA-Z0-9-_]+$
71+
example: prod
72+
required: true
73+
in: path
74+
responses:
75+
'204':
76+
description: Tag successfully deleted
77+
'400':
78+
$ref: ../components/responses/400.yaml
79+
'401':
80+
$ref: ../components/responses/401.yaml
81+
'403':
82+
$ref: ../components/responses/403.yaml
83+
'404':
84+
$ref: ../components/responses/404.yaml
85+
'500':
86+
$ref: ../components/responses/500.yaml

0 commit comments

Comments
 (0)