-
Notifications
You must be signed in to change notification settings - Fork 5
Fix programmatic method invocation. #9
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +1,90 @@ | ||
| # Template | ||
|
|
||
| This component is used behind the scenes to deploy your YAML templates. It is loaded by the serverless CLI and executed just as any other component. | ||
| However, there's a lot you can do with this component programmatically. See the sections below for some examples. | ||
|
|
||
| ### Programmatic usage and custom environments | ||
|
|
||
| To deploy to multiple environments you must utilize the programmatic API, via `serverless.js` file. | ||
|
|
||
| `serverless.js` | ||
|
|
||
| ```js | ||
| const { Component } = require('@serverless/core') | ||
|
|
||
| class Deploy extends Component { | ||
| async default(inputs = {}) { | ||
| const { env } = inputs | ||
|
|
||
| const template = await this.load('@serverless/template', env) | ||
| return await template({ template: __dirname + '/serverless.yml' }) | ||
| } | ||
|
|
||
| async remove(inputs = {}) { | ||
| const { env } = inputs | ||
|
|
||
| const template = await this.load('@serverless/template', env) | ||
| await template.remove(inputs) | ||
| } | ||
| } | ||
|
|
||
| module.exports = Deploy | ||
| ``` | ||
|
|
||
| `serverless.yml` | ||
|
|
||
| ```yml | ||
| name: test | ||
|
|
||
| lambda: | ||
| component: '@serverless/function' | ||
| inputs: | ||
| name: my-function | ||
| description: My Serverless Function | ||
| memory: 128 | ||
| timeout: 20 | ||
| code: './code' | ||
| hanlder": 'handler.handler' | ||
| region: us-east-1 | ||
| runtime: nodejs10.x | ||
| ``` | ||
|
|
||
| Invoking `sls --env=dev` will result in state files in `.serverless/` being prefixed with the value of your `env`: | ||
| `Deploy.dev.json`, etc. That way you can deploy unlimited environments, add pre/post processing, load whatever `.env` you need, etc. | ||
|
|
||
| ### Running custom methods on a template | ||
|
|
||
| A template itself does not contain any methods so custom methods are executed on the specific template aliases. | ||
|
|
||
| `sls install --component lambda` will load the `lambda` alias from your template, instantiate the corresponding component, and execute the `install` method passing in the inputs you specify via CLI parameters. | ||
| Inputs from the template itself are not passed as they can not be interpreted/resolved without running the entire template. | ||
|
|
||
| You can pass as many `--component` parameters as you need. | ||
|
|
||
| ### Running custom methods programmatically | ||
|
|
||
| `serverless.js` | ||
|
|
||
| ```js | ||
| const { Component } = require('@serverless/core') | ||
|
|
||
| class Deploy extends Component { | ||
| /* ...skipped default method for brevity ... */ | ||
|
|
||
| async install(inputs = {}) { | ||
| const template = await this.load('@serverless/template') | ||
| await template.install({ template: __dirname + '/serverless.yml', ...inputs }) | ||
| } | ||
| } | ||
|
|
||
| module.exports = Deploy | ||
| ``` | ||
|
|
||
| When invoking methods on a `template` instance, you always need to pass in a path to the template file or a template object. | ||
|
|
||
| Running `sls install --component lambda --debug` - this will load the template, find the `lambda` alias, and invoke the `install` method on the instance of the component. | ||
|
|
||
| ### Couldn't find what you were looking for? | ||
|
|
||
| Visit our github and file an issue with as much info as possible about your problem. | ||
| If you think you've found a bug - please do post a complete reproduction repo. It will help us and our contributors to help you much faster. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -353,8 +353,12 @@ const createCustomMethodHandler = (instance, method) => { | |
| instance.context.debug( | ||
| `Attempting to run method "${method}" on template aliases: ${components.join(', ')}` | ||
| ) | ||
|
|
||
| // Make sure the template is an object | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is it important to make sure the template is an object? Can this be explained in this comment? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On line 349 above, is it prudent to throw an Error? Perhaps if there was a proper testing framework that would guarantee the behavior of this, however since there is no framework and this is a core part of serverless components, I suggest not throwing an error.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| const templateObject = await getTemplate({ template }) | ||
|
|
||
| // Load template components | ||
| const templateComponents = await getAllComponents(template) | ||
| const templateComponents = await getAllComponents(templateObject) | ||
|
|
||
| // Get only the requested components ("component" input) | ||
| const componentsToRun = Object.keys(templateComponents) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this happening? I would suspect that properties from a promise are bleeding through here. However guarding against
thendoes not guarantee that other things may also cause trouble. I suggest thatcreateCustomMethodHandlershould be renamedtryCreateCustomMethodHandlerand if a component cannot be found, instead of creating an error, rather just returnobj[prop]There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately that is not possible, since you're passing template path at method invocation and not Template component construction.