Skip to content

Commit 0cb2cb1

Browse files
committed
Apply code review feedback
1 parent 60af644 commit 0cb2cb1

File tree

6 files changed

+29
-23
lines changed

6 files changed

+29
-23
lines changed

docs/generated/api.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -1048,7 +1048,7 @@
10481048
{
10491049
"kind": "MethodSignature",
10501050
"canonicalReference": "@google-cloud/functions-framework!InvocationFormat#deserializeRequest:member(1)",
1051-
"docComment": "/**\n * @param request - the request body as raw bytes\n *\n * @param headers - the headers received on the HTTP request as a map\n */\n",
1051+
"docComment": "/**\n * Creates an instance of the request type from an invocation request.\n *\n * @param request - the request body as raw bytes\n */\n",
10521052
"excerptTokens": [
10531053
{
10541054
"kind": "Content",
@@ -1103,7 +1103,7 @@
11031103
{
11041104
"kind": "MethodSignature",
11051105
"canonicalReference": "@google-cloud/functions-framework!InvocationFormat#serializeResponse:member(1)",
1106-
"docComment": "/**\n * @param response - \n *\n * @param responseHeaders - mutable object providing headers that will be set on the response\n */\n",
1106+
"docComment": "/**\n * Writes the response type to the invocation result.\n *\n * @param responseWriter - interface for writing to the invocation result\n *\n * @param response - the response object\n */\n",
11071107
"excerptTokens": [
11081108
{
11091109
"kind": "Content",

docs/generated/api.md

-2
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,7 @@ export interface HttpFunction {
7272

7373
// @public
7474
export interface InvocationFormat<T, U> {
75-
// (undocumented)
7675
deserializeRequest(request: InvocationRequest): T | Promise<T>;
77-
// (undocumented)
7876
serializeResponse(responseWriter: InvocationResponse, response: U): void | Promise<void>;
7977
}
8078

src/functions.ts

+6-3
Original file line numberDiff line numberDiff line change
@@ -176,15 +176,17 @@ export interface InvocationResponse {
176176
*/
177177
export interface InvocationFormat<T, U> {
178178
/**
179+
* Creates an instance of the request type from an invocation request.
179180
*
180181
* @param request the request body as raw bytes
181-
* @param headers the headers received on the HTTP request as a map
182182
*/
183183
deserializeRequest(request: InvocationRequest): T | Promise<T>;
184+
184185
/**
186+
* Writes the response type to the invocation result.
185187
*
186-
* @param response
187-
* @param responseHeaders mutable object providing headers that will be set on the response
188+
* @param responseWriter interface for writing to the invocation result
189+
* @param response the response object
188190
*/
189191
serializeResponse(
190192
responseWriter: InvocationResponse,
@@ -199,6 +201,7 @@ export class JsonInvocationFormat<T, U> implements InvocationFormat<T, U> {
199201
deserializeRequest(request: InvocationRequest): T {
200202
const body = request.body();
201203
if (typeof body !== 'string') {
204+
console.log(typeof body);
202205
throw new Error('Unsupported Content-Type, expected application/json');
203206
}
204207
try {

src/server.ts

+9-15
Original file line numberDiff line numberDiff line change
@@ -85,24 +85,18 @@ export function getServer(
8585
};
8686

8787
// Apply middleware
88-
if (functionSignatureType === 'typed') {
89-
app.use(
90-
bodyParser.text({
91-
limit: requestLimit,
92-
type: '*/json',
93-
})
94-
);
95-
app.use(
96-
bodyParser.text({
97-
limit: requestLimit,
98-
type: 'text/*',
99-
})
100-
);
101-
} else {
88+
if (functionSignatureType !== 'typed') {
89+
// If the function is not typed then JSON parsing can be done automatically, otherwise the
90+
// functions format must determine deserialization.
10291
app.use(bodyParser.json(cloudEventsBodySavingOptions));
10392
app.use(bodyParser.json(defaultBodySavingOptions));
104-
app.use(bodyParser.text(defaultBodySavingOptions));
93+
} else {
94+
const jsonParserOptions = Object.assign({}, defaultBodySavingOptions, {
95+
type: 'application/json',
96+
});
97+
app.use(bodyParser.text(jsonParserOptions));
10598
}
99+
app.use(bodyParser.text(defaultBodySavingOptions));
106100
app.use(bodyParser.urlencoded(urlEncodedOptions));
107101
// The parser will process ALL content types so MUST come last.
108102
// Subsequent parsers will be skipped when one is matched.

test/function_registry.ts

+11
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
// limitations under the License.
1414
import * as assert from 'assert';
1515
import * as FunctionRegistry from '../src/function_registry';
16+
import {JsonInvocationFormat} from '../src';
1617

1718
describe('function_registry', () => {
1819
it('can register http functions', () => {
@@ -31,6 +32,16 @@ describe('function_registry', () => {
3132
assert.deepStrictEqual((userFunction as () => string)(), 'CE_PASS');
3233
});
3334

35+
it('can register typed functions', () => {
36+
FunctionRegistry.typed('typedFunction', (identity: string) => identity);
37+
const {userFunction, signatureType} =
38+
FunctionRegistry.getRegisteredFunction('typedFunction')!;
39+
assert.deepStrictEqual('typed', signatureType);
40+
41+
assert.ok(!(userFunction instanceof Function));
42+
assert.ok(userFunction.format instanceof JsonInvocationFormat);
43+
});
44+
3445
it('throws an error if you try to register a function with an invalid URL', () => {
3546
// Valid function names
3647
const validFunctions = ['httpFunction', 'ceFunction', 'test-func'];

test/integration/typed.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ describe('Typed Function', () => {
9898
name: 'POST malformatted JSON',
9999
requestBody: 'ASDF',
100100
expectedBody:
101-
'Failed to parse malformatted JSON in request: Unexpected token A in JSON at position 0',
101+
/Failed to parse malformatted JSON in request.*/,
102102
expectedStatus: 400,
103103
expectedCallCount: 0,
104104
},

0 commit comments

Comments
 (0)