From 83d0bb89672aa90d985b82c85888052fe93dd38c Mon Sep 17 00:00:00 2001 From: Jeff Kalbacher Date: Mon, 12 Sep 2022 10:39:41 -0700 Subject: [PATCH 1/2] fix: use camel casing on last path param to adhere to graphQL regex --- graphql.go | 3 +++ graphql_test.go | 25 +++++++++++++++++++++++-- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/graphql.go b/graphql.go index 0bd77632..5f0e093b 100644 --- a/graphql.go +++ b/graphql.go @@ -172,6 +172,8 @@ func (r *Router) handleOperation(config *GraphQLConfig, parentName string, field // `/things/{thing-id}` -> `thingsItem(thingId)` // `/things/{thing-id}/sub` -> `sub(thingId)` parts := strings.Split(strings.Trim(resource.path, "/"), "/") + // v2, {org}, channels, {channel-id}, preview-streams + // last = preview-streams last := parts[len(parts)-1] for i := len(parts) - 1; i >= 0; i-- { if parts[i][0] == '{' { @@ -182,6 +184,7 @@ func (r *Router) handleOperation(config *GraphQLConfig, parentName string, field } break } + last = casing.LowerCamel(last) // Setup input arguments (i.e. OpenAPI operation params). args := graphql.FieldConfigArgument{} diff --git a/graphql_test.go b/graphql_test.go index fb5fc59a..bab32ed9 100644 --- a/graphql_test.go +++ b/graphql_test.go @@ -49,7 +49,12 @@ type StoreSummary struct { ID string `json:"id" graphParam:"store-id" doc:"Store ID"` } +type StoreName struct { + Name string `json:"name" graphParam:"store-name" doc:"Store Name"` +} + type Store struct { + StoreName StoreSummary URL string `json:"url" doc:"Web link to buy product"` } @@ -57,8 +62,8 @@ type Store struct { func TestGraphQL(t *testing.T) { now, _ := time.Parse(time.RFC3339, "2022-02-22T22:22:22Z") - amazon := &Store{StoreSummary: StoreSummary{ID: "amazon"}, URL: "https://www.amazon.com/"} - target := &Store{StoreSummary: StoreSummary{ID: "target"}, URL: "https://www.target.com/"} + amazon := &Store{StoreSummary: StoreSummary{ID: "amazon"}, URL: "https://www.amazon.com/", StoreName: StoreName{"amazon"}} + target := &Store{StoreSummary: StoreSummary{ID: "target"}, URL: "https://www.target.com/", StoreName: StoreName{"target"}} xsx := &Product{ProductSummary: ProductSummary{ID: "xbox_series_x"}, SuggestedPrice: 499.99, Created: &now, Metadata: map[string]string{"foo": "bar"}, stores: map[string]*Store{"amazon": amazon, "target": target}, Empty: &struct{}{}} ps5 := &Product{ProductSummary: ProductSummary{ID: "playstation_ps5"}, SuggestedPrice: 499.99, Created: &now, stores: map[string]*Store{"amazon": amazon}} @@ -194,6 +199,21 @@ func TestGraphQL(t *testing.T) { ctx.WriteModel(http.StatusOK, categories[input.CategoryID].products[input.ProductID].stores[input.StoreID]) }) + app.Resource("/categories/{category-id}/products/{product-id}/stores/{store-id}/store-name").Get("get-store-name", "doc", + NewResponse(http.StatusOK, "").Model(&StoreName{}), + NewResponse(http.StatusNotFound, "").Model(&ErrorModel{}), + ).Run(func(ctx Context, input struct { + CategoryParam + ProductParam + StoreID string `path:"store-id" doc:"Store ID"` + }) { + if categories[input.CategoryID] == nil || categories[input.CategoryID].products[input.ProductID] == nil { + ctx.WriteError(http.StatusNotFound, "Not found") + return + } + ctx.WriteModel(http.StatusOK, categories[input.CategoryID].products[input.ProductID].stores[input.StoreID].StoreName) + }) + app.Resource("/ignored").Get("get-ignored", "doc", NewResponse(http.StatusOK, "").Model(struct{ ID string }{}), ).Run(func(ctx Context) { @@ -326,6 +346,7 @@ data: - name: categoriesItem - name: products - name: productsItem + - name: storeName - name: stores - name: storesItem `, "\t", " ", -1), w.Body.String()) From 8221929ac5d81c82f8be5e58ea719a70a2803489 Mon Sep 17 00:00:00 2001 From: Jeff Kalbacher Date: Mon, 12 Sep 2022 10:40:56 -0700 Subject: [PATCH 2/2] remove temporary comments --- graphql.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/graphql.go b/graphql.go index 5f0e093b..af46ef80 100644 --- a/graphql.go +++ b/graphql.go @@ -172,8 +172,6 @@ func (r *Router) handleOperation(config *GraphQLConfig, parentName string, field // `/things/{thing-id}` -> `thingsItem(thingId)` // `/things/{thing-id}/sub` -> `sub(thingId)` parts := strings.Split(strings.Trim(resource.path, "/"), "/") - // v2, {org}, channels, {channel-id}, preview-streams - // last = preview-streams last := parts[len(parts)-1] for i := len(parts) - 1; i >= 0; i-- { if parts[i][0] == '{' {