Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: introduce declarative function signatures (#347)
This commit introduces an API that allows developers to explictly register their functions against the framework so that they can declaratively configure thier signature type.
- Loading branch information
1 parent
51cb666
commit db1ba9e
Showing
7 changed files
with
249 additions
and
58 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
// Copyright 2021 Google LLC | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
import {HttpFunction, CloudEventFunction, HandlerFunction} from './functions'; | ||
import {SignatureType} from './types'; | ||
|
||
interface RegisteredFunction { | ||
signatureType: SignatureType; | ||
userFunction: HandlerFunction; | ||
} | ||
|
||
/** | ||
* Singleton map to hold the registered functions | ||
*/ | ||
const registrationContainer = new Map<string, RegisteredFunction>(); | ||
|
||
/** | ||
* Helper method to store a registered function in the registration container | ||
*/ | ||
const register = ( | ||
functionName: string, | ||
signatureType: SignatureType, | ||
userFunction: HandlerFunction | ||
): void => { | ||
registrationContainer.set(functionName, { | ||
signatureType, | ||
userFunction, | ||
}); | ||
}; | ||
|
||
/** | ||
* Get a declaratively registered function | ||
* @param functionName the name with which the function was registered | ||
* @returns the registered function and signature type or undefined no function matching | ||
* the provided name has been registered. | ||
*/ | ||
export const getRegisteredFunction = ( | ||
functionName: string | ||
): RegisteredFunction | undefined => { | ||
return registrationContainer.get(functionName); | ||
}; | ||
|
||
/** | ||
* Register a function that responds to HTTP requests. | ||
* @param functionName the name of the function | ||
* @param handler the function to invoke when handling HTTP requests | ||
*/ | ||
export const http = (functionName: string, handler: HttpFunction): void => { | ||
register(functionName, 'http', handler); | ||
}; | ||
|
||
/** | ||
* Register a function that handles CloudEvents. | ||
* @param functionName the name of the function | ||
* @param handler the function to trigger when handling cloudevents | ||
*/ | ||
export const cloudevent = ( | ||
functionName: string, | ||
handler: CloudEventFunction | ||
): void => { | ||
register(functionName, 'cloudevent', handler); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
// Copyright 2019 Google LLC | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
// Functions framework entry point that configures and starts Node.js server | ||
// that runs user's code on HTTP request. | ||
import {getUserFunction} from './loader'; | ||
import {ErrorHandler} from './invoker'; | ||
import {getServer} from './server'; | ||
import {parseOptions, helpText, OptionsError} from './options'; | ||
|
||
/** | ||
* Main entrypoint for the functions framework that loads the user's function | ||
* and starts the HTTP server. | ||
*/ | ||
export const main = async () => { | ||
try { | ||
const options = parseOptions(); | ||
|
||
if (options.printHelp) { | ||
console.error(helpText); | ||
return; | ||
} | ||
const loadedFunction = await getUserFunction( | ||
options.sourceLocation, | ||
options.target, | ||
options.signatureType | ||
); | ||
if (!loadedFunction) { | ||
console.error('Could not load the function, shutting down.'); | ||
// eslint-disable-next-line no-process-exit | ||
process.exit(1); | ||
} | ||
const {userFunction, signatureType} = loadedFunction; | ||
const server = getServer(userFunction!, signatureType); | ||
const errorHandler = new ErrorHandler(server); | ||
server | ||
.listen(options.port, () => { | ||
errorHandler.register(); | ||
if (process.env.NODE_ENV !== 'production') { | ||
console.log('Serving function...'); | ||
console.log(`Function: ${options.target}`); | ||
console.log(`Signature type: ${signatureType}`); | ||
console.log(`URL: http://localhost:${options.port}/`); | ||
} | ||
}) | ||
.setTimeout(0); // Disable automatic timeout on incoming connections. | ||
} catch (e) { | ||
if (e instanceof OptionsError) { | ||
console.error(e.message); | ||
// eslint-disable-next-line no-process-exit | ||
process.exit(1); | ||
} | ||
throw e; | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
// Copyright 2019 Google LLC | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
import * as assert from 'assert'; | ||
import * as FunctionRegistry from '../src/function_registry'; | ||
|
||
describe('function_registry', () => { | ||
it('can register http functions', () => { | ||
FunctionRegistry.http('httpFunction', () => 'HTTP_PASS'); | ||
const { | ||
userFunction, | ||
signatureType, | ||
} = FunctionRegistry.getRegisteredFunction('httpFunction')!; | ||
assert.deepStrictEqual('http', signatureType); | ||
assert.deepStrictEqual((userFunction as () => string)(), 'HTTP_PASS'); | ||
}); | ||
|
||
it('can register cloudevent functions', () => { | ||
FunctionRegistry.cloudevent('ceFunction', () => 'CE_PASS'); | ||
const { | ||
userFunction, | ||
signatureType, | ||
} = FunctionRegistry.getRegisteredFunction('ceFunction')!; | ||
assert.deepStrictEqual('cloudevent', signatureType); | ||
assert.deepStrictEqual((userFunction as () => string)(), 'CE_PASS'); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters