From ef9f14b497a893fd30043739df82f84d4f3b3a50 Mon Sep 17 00:00:00 2001 From: Daniel Pupius Date: Thu, 30 May 2024 16:54:13 -0700 Subject: [PATCH] Support query params on DELETE requests, closes #29 --- generator/template.go | 2 +- generator/template_test.go | 3 + .../defaultConfig/defaultConfig_test.ts | 8 ++ .../noStaticClasses/noStaticClasses_test.ts | 85 +++++++++---------- test/integration/protos/service.proto | 14 +++ test/integration/service.go | 4 + 6 files changed, 68 insertions(+), 48 deletions(-) diff --git a/generator/template.go b/generator/template.go index c1baeb4..df2a76d 100644 --- a/generator/template.go +++ b/generator/template.go @@ -96,7 +96,7 @@ func renderURL(r *registry.Registry) func(method data.Method) string { } urlPathParams := fmt.Sprintf("[%s]", strings.Join(fieldsInPath, ", ")) - if !method.ClientStreaming && method.HTTPMethod == "GET" { + if !method.ClientStreaming && (method.HTTPMethod == "GET" || method.HTTPMethod == "DELETE") { // parse the url to check for query string parsedURL, err := url.Parse(methodURL) if err != nil { diff --git a/generator/template_test.go b/generator/template_test.go index 61b34af..9b0e1ca 100644 --- a/generator/template_test.go +++ b/generator/template_test.go @@ -24,6 +24,9 @@ func TestFieldName(t *testing.T) { {useProtoNames: false, input: "foo3_bar", want: "foo3Bar"}, {useProtoNames: false, input: "foo_3bar", want: "foo3bar"}, {useProtoNames: false, input: "foo_3_bar", want: "foo3Bar"}, + + {useProtoNames: true, input: "k8s_field", want: "k8s_field"}, + {useProtoNames: true, input: "foo_bar", want: "foo_bar"}, } for _, tt := range tests { t.Run(tt.input, func(t *testing.T) { diff --git a/test/integration/defaultConfig/defaultConfig_test.ts b/test/integration/defaultConfig/defaultConfig_test.ts index b58e5bf..d3b6fdd 100644 --- a/test/integration/defaultConfig/defaultConfig_test.ts +++ b/test/integration/defaultConfig/defaultConfig_test.ts @@ -100,6 +100,14 @@ describe("test default configuration", () => { expect(result).to.be.empty; }); + it("http delete with query params", async () => { + const result = await CounterService.HTTPDeleteWithParams( + { id: 10, reason: "test" }, + { pathPrefix: "http://localhost:8081" } + ); + expect(result.reason).to.be.equal("test"); + }); + it("http get request with url search parameters", async () => { const result = await CounterService.HTTPGetWithURLSearchParams( { a: 10, b: { b: 0 }, c: [23, 25], d: { d: 12 } }, diff --git a/test/integration/noStaticClasses/noStaticClasses_test.ts b/test/integration/noStaticClasses/noStaticClasses_test.ts index 781d43f..cf102eb 100644 --- a/test/integration/noStaticClasses/noStaticClasses_test.ts +++ b/test/integration/noStaticClasses/noStaticClasses_test.ts @@ -10,20 +10,14 @@ import { b64Decode } from "./fetch.pb"; describe("test static functions", () => { it("unary request", async () => { - const result = await increment( - { counter: 199 }, - { pathPrefix: "http://localhost:8081" } - ); + const result = await increment({ counter: 199 }); expect(result.result).to.equal(200); }); it("failing unary request", async () => { try { - await failingIncrement( - { counter: 199 }, - { pathPrefix: "http://localhost:8081" } - ); + await failingIncrement({ counter: 199 }); expect.fail("expected call to throw"); } catch (e) { expect(e).to.have.property("message", "this increment does not work"); @@ -33,10 +27,8 @@ describe("test static functions", () => { it("streaming request", async () => { const response = [] as number[]; - await streamingIncrements( - { counter: 1 }, - (resp) => response.push(resp.result), - { pathPrefix: "http://localhost:8081" } + await streamingIncrements({ counter: 1 }, (resp) => + response.push(resp.result) ); expect(response).to.deep.equal([2, 3, 4, 5, 6]); }); @@ -67,65 +59,67 @@ describe("test with client class", () => { it("http get check request", async () => { const req = { numToIncrease: 10 } as HttpGetRequest; - const result = await client.httpGet(req, { - pathPrefix: "http://localhost:8081", - }); + const result = await client.httpGet(req); expect(result.result).to.equal(11); }); it("http post body check request with nested body path", async () => { - const result = await client.httpPostWithNestedBodyPath( - { a: 10, req: { b: 15 }, c: 0 }, - { pathPrefix: "http://localhost:8081" } - ); + const result = await client.httpPostWithNestedBodyPath({ + a: 10, + req: { b: 15 }, + c: 0, + }); expect(result.postResult).to.equal(25); }); it("http post body check request with star in path", async () => { - const result = await client.httpPostWithStarBodyPath( - { a: 10, req: { b: 15 }, c: 23 }, - { pathPrefix: "http://localhost:8081" } - ); + const result = await client.httpPostWithStarBodyPath({ + a: 10, + req: { b: 15 }, + c: 23, + }); expect(result.postResult).to.equal(48); }); it("able to communicate with external message reference without package defined", async () => { - const result = await client.externalMessage( - { content: "hello" }, - { pathPrefix: "http://localhost:8081" } - ); + const result = await client.externalMessage({ content: "hello" }); expect(result.result).to.equal("hello!!"); }); it("http patch request with star in path", async () => { - const result = await client.httpPatch( - { a: 10, c: 23 }, - { pathPrefix: "http://localhost:8081" } - ); + const result = await client.httpPatch({ a: 10, c: 23 }); expect(result.patchResult).to.equal(33); }); it("http delete check request", async () => { - const result = await client.httpDelete( - { a: 10 }, - { pathPrefix: "http://localhost:8081" } - ); + const result = await client.httpDelete({ a: 10 }); expect(result).to.be.empty; }); + it("http delete with query params", async () => { + const result = await client.httpDeleteWithParams({ + id: 10, + reason: "test", + }); + expect(result.reason).to.be.equal("test"); + }); + it("http get request with url search parameters", async () => { - const result = await client.httpGetWithURLSearchParams( - { a: 10, b: { b: 0 }, c: [23, 25], d: { d: 12 } }, - { pathPrefix: "http://localhost:8081" } - ); + const result = await client.httpGetWithURLSearchParams({ + a: 10, + b: { b: 0 }, + c: [23, 25], + d: { d: 12 }, + }); expect(result.urlSearchParamsResult).to.equal(70); }); it("http get request with zero value url search parameters", async () => { - const result = await client.httpGetWithZeroValueURLSearchParams( - { a: "A", b: "", c: { c: 1, d: [1, 0, 2], e: false } }, - { pathPrefix: "http://localhost:8081" } - ); + const result = await client.httpGetWithZeroValueURLSearchParams({ + a: "A", + b: "", + c: { c: 1, d: [1, 0, 2], e: false }, + }); expect(result).to.deep.equal({ a: "A", b: "hello", @@ -134,10 +128,7 @@ describe("test with client class", () => { }); it("http get request with optional fields", async () => { - const result = await client.httpGetWithOptionalFields( - {}, - { pathPrefix: "http://localhost:8081" } - ); + const result = await client.httpGetWithOptionalFields({}); expect(result).to.deep.equal({ // all empty fields will be excluded. diff --git a/test/integration/protos/service.proto b/test/integration/protos/service.proto index a23a1e5..51cc966 100644 --- a/test/integration/protos/service.proto +++ b/test/integration/protos/service.proto @@ -77,6 +77,15 @@ message HttpDeleteRequest { int32 a = 1; } +message HttpDeleteWithParamsRequest { + int32 id = 1; + string reason = 2; +} + +message HttpDeleteWithParamsResponse { + string reason = 1; +} + message HTTPGetWithURLSearchParamsRequest { int32 a = 1; PostRequest b = 2; @@ -200,6 +209,11 @@ service CounterService { delete: "/delete/{a}" }; } + rpc HTTPDeleteWithParams(HttpDeleteWithParamsRequest) returns (HttpDeleteWithParamsResponse) { + option (google.api.http) = { + delete: "/delete/{id}" + }; + } rpc ExternalMessage(ExternalRequest) returns (ExternalResponse); rpc HTTPGetWithURLSearchParams(HTTPGetWithURLSearchParamsRequest) returns (HTTPGetWithURLSearchParamsResponse) { option (google.api.http) = { diff --git a/test/integration/service.go b/test/integration/service.go index 1da0900..361bb99 100644 --- a/test/integration/service.go +++ b/test/integration/service.go @@ -82,6 +82,10 @@ func (r *RealCounterService) HTTPDelete(ctx context.Context, req *HttpDeleteRequ return &emptypb.Empty{}, nil } +func (r *RealCounterService) HTTPDeleteWithParams(ctx context.Context, req *HttpDeleteWithParamsRequest) (*HttpDeleteWithParamsResponse, error) { + return &HttpDeleteWithParamsResponse{Reason: req.Reason}, nil +} + func (r *RealCounterService) HTTPGetWithURLSearchParams(ctx context.Context, in *HTTPGetWithURLSearchParamsRequest) (*HTTPGetWithURLSearchParamsResponse, error) { totalC := 0 for _, c := range in.GetC() {