Skip to content

Commit

Permalink
feat(openapi): add operationIds
Browse files Browse the repository at this point in the history
add valid operationIDs, which improves the 
openapi-generator generated clients.
  • Loading branch information
toumorokoshi committed Dec 11, 2024
1 parent 39517cc commit b1e7aa2
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 17 deletions.
15 changes: 8 additions & 7 deletions pkg/api/openapi.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"strings"

"github.com/aep-dev/aep-lib-go/pkg/cases"
"github.com/aep-dev/aep-lib-go/pkg/constants"
"github.com/aep-dev/aep-lib-go/pkg/openapi"
)
Expand Down Expand Up @@ -92,7 +93,7 @@ func ConvertToOpenAPI(api *API) (*openapi.OpenAPI, error) {
}
}
addMethodToPath(paths, listPath, "get", openapi.Operation{
OperationID: r.Singular + ".list",
OperationID: fmt.Sprintf("List%s", cases.UpperFirst(r.Singular)),
Description: fmt.Sprintf("List method for %s", r.Singular),
Parameters: append(pwp.Params,
openapi.Parameter{
Expand Down Expand Up @@ -139,7 +140,7 @@ func ConvertToOpenAPI(api *API) (*openapi.OpenAPI, error) {
})
}
addMethodToPath(paths, createPath, "post", openapi.Operation{
OperationID: r.Singular + ".create",
OperationID: fmt.Sprintf("Create%s", cases.UpperFirst(r.Singular)),
Description: fmt.Sprintf("Create method for %s", r.Singular),
Parameters: params,
RequestBody: &bodyParam,
Expand All @@ -150,7 +151,7 @@ func ConvertToOpenAPI(api *API) (*openapi.OpenAPI, error) {
}
if r.GetMethod != nil {
addMethodToPath(paths, resourcePath, "get", openapi.Operation{
OperationID: r.Singular + ".get",
OperationID: fmt.Sprintf("Get%s", cases.UpperFirst(r.Singular)),
Description: fmt.Sprintf("Get method for %s", r.Singular),
Parameters: append(pwp.Params, idParam),
Responses: map[string]openapi.Response{
Expand All @@ -160,7 +161,7 @@ func ConvertToOpenAPI(api *API) (*openapi.OpenAPI, error) {
}
if r.UpdateMethod != nil {
addMethodToPath(paths, resourcePath, "patch", openapi.Operation{
OperationID: r.Singular + ".update",
OperationID: fmt.Sprintf("Update%s", cases.UpperFirst(r.Singular)),
Description: fmt.Sprintf("Update method for %s", r.Singular),
Parameters: append(pwp.Params, idParam),
RequestBody: &bodyParam,
Expand All @@ -182,7 +183,7 @@ func ConvertToOpenAPI(api *API) (*openapi.OpenAPI, error) {
})
}
addMethodToPath(paths, resourcePath, "delete", openapi.Operation{
OperationID: r.Singular + ".delete",
OperationID: fmt.Sprintf("Delete%s", cases.UpperFirst(r.Singular)),
Description: fmt.Sprintf("Delete method for %s", r.Singular),
Parameters: params,
Responses: map[string]openapi.Response{
Expand All @@ -199,7 +200,7 @@ func ConvertToOpenAPI(api *API) (*openapi.OpenAPI, error) {
}
if r.ApplyMethod != nil {
addMethodToPath(paths, resourcePath, "put", openapi.Operation{
OperationID: r.Singular + ".apply",
OperationID: fmt.Sprintf("Apply%s", cases.UpperFirst(r.Singular)),
Description: fmt.Sprintf("Apply method for %s", r.Singular),
Parameters: append(pwp.Params, idParam),
RequestBody: &bodyParam,
Expand All @@ -215,7 +216,7 @@ func ConvertToOpenAPI(api *API) (*openapi.OpenAPI, error) {
}
cmPath := fmt.Sprintf("%s:%s", resourcePath, custom.Name)
methodInfo := openapi.Operation{
OperationID: r.Singular + ":" + custom.Name,
OperationID: fmt.Sprintf(":%s%s", cases.UpperFirst(custom.Name), cases.UpperFirst(r.Singular)),
Description: fmt.Sprintf("Custom method %s for %s", custom.Name, r.Singular),
Parameters: append(pwp.Params, idParam),
Responses: map[string]openapi.Response{
Expand Down
99 changes: 89 additions & 10 deletions pkg/api/openapi_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,22 @@ func TestToOpenAPI(t *testing.T) {
CreateMethod: &CreateMethod{},
UpdateMethod: &UpdateMethod{},
DeleteMethod: &DeleteMethod{},
CustomMethods: []*CustomMethod{
{
Name: "archive",
Method: "POST",
Request: &openapi.Schema{
Type: "object",
Properties: map[string]openapi.Schema{},
},
Response: &openapi.Schema{
Type: "object",
Properties: map[string]openapi.Schema{
"archived": {Type: "boolean"},
},
},
},
},
}
publisher.Children = append(publisher.Children, book)
exampleAPI := &API{
Expand Down Expand Up @@ -80,20 +96,63 @@ func TestToOpenAPI(t *testing.T) {
},
expectedOperations: map[string]openapi.PathItem{
"/publishers": {
Get: &openapi.Operation{},
Post: &openapi.Operation{},
Get: &openapi.Operation{
OperationID: "ListPublisher",
},
Post: &openapi.Operation{
OperationID: "CreatePublisher",
},
},
"/publishers/{publisher}": {
Get: &openapi.Operation{},
Get: &openapi.Operation{
OperationID: "GetPublisher",
},
},
"/publishers/{publisher}/books": {
Get: &openapi.Operation{},
Post: &openapi.Operation{},
Get: &openapi.Operation{
OperationID: "ListBook",
},
Post: &openapi.Operation{
OperationID: "CreateBook",
},
},
"/publishers/{publisher}/books/{book}": {
Get: &openapi.Operation{},
Put: &openapi.Operation{},
Delete: &openapi.Operation{},
Get: &openapi.Operation{
OperationID: "GetBook",
},
Patch: &openapi.Operation{
OperationID: "UpdateBook",
},
Delete: &openapi.Operation{
OperationID: "DeleteBook",
},
},
"/publishers/{publisher}/books/{book}:archive": {
Post: &openapi.Operation{
OperationID: ":ArchiveBook",
RequestBody: &openapi.RequestBody{
Required: true,
Content: map[string]openapi.MediaType{
"application/json": {
Schema: &openapi.Schema{},
},
},
},
Responses: map[string]openapi.Response{
"200": {
Content: map[string]openapi.MediaType{
"application/json": {
Schema: &openapi.Schema{
Type: "object",
Properties: map[string]openapi.Schema{
"archived": {Type: "boolean"},
},
},
},
},
},
},
},
},
},
expectedListSchemas: map[string]*openapi.Schema{
Expand Down Expand Up @@ -148,24 +207,44 @@ func TestToOpenAPI(t *testing.T) {
assert.True(t, exists, "Expected schema %s not found", schema)
}

// Verify operations exist
// Verify operations exist and have correct operationIds
for path, operations := range tt.expectedOperations {
pathItem, exists := openAPI.Paths[path]
assert.True(t, exists, "Expected path %s not found", path)
if operations.Get != nil {
assert.NotNil(t, pathItem.Get, "expected get operation for path %s", path)
if operations.Get.OperationID != "" {
assert.Equal(t, operations.Get.OperationID, pathItem.Get.OperationID,
"expected matching operationId for GET %s", path)
}
}
if operations.Patch != nil {
assert.NotNil(t, pathItem.Patch, "expected patch operation for path %s", path)
if operations.Patch.OperationID != "" {
assert.Equal(t, operations.Patch.OperationID, pathItem.Patch.OperationID,
"expected matching operationId for PATCH %s", path)
}
}
if operations.Post != nil {
assert.NotNil(t, pathItem.Post, "expected post operation for path %s", path)
if operations.Post.OperationID != "" {
assert.Equal(t, operations.Post.OperationID, pathItem.Post.OperationID,
"expected matching operationId for POST %s", path)
}
}
if operations.Put != nil {
assert.NotNil(t, operations.Put, "expected put operation for path %s", path)
assert.NotNil(t, pathItem.Put, "expected put operation for path %s", path)
if operations.Put.OperationID != "" {
assert.Equal(t, operations.Put.OperationID, pathItem.Put.OperationID,
"expected matching operationId for PUT %s", path)
}
}
if operations.Delete != nil {
assert.NotNil(t, pathItem.Delete, "expected delete operation for path %s", path)
if operations.Delete.OperationID != "" {
assert.Equal(t, operations.Delete.OperationID, pathItem.Delete.OperationID,
"expected matching operationId for DELETE %s", path)
}
}
}

Expand Down

0 comments on commit b1e7aa2

Please sign in to comment.