Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Using custom function template with AWS Amplify

Using custom function template with AWS Amplify


November 20, 2021

More Decks by MURAKAMI Masahiko

Other Decks in Programming


  1. Introductions Masahiko Murakam i • Software Developer - ESM, Inc

    . • Amplify Japan User Group Core Membe r • Background : • TypeScript/JavaScrip t • Node.j s • Jav a • Twitter: https://twitter.com/fossamagna • GitHub: https://github.com/fossamagna
  2. Agenda •What is AWS Amplify function template ? •Authoring a

    custom function templat e •Third-party function templates
  3. What is AWS Amplify function template? • Function template is

    resources that are added by executing the amplify function add comman d • Lambda source code (ex: *.js, *.py, *.go *.java, *cs ) • Exclude CloudFormation template
  4. What is AWS Amplify function template? • Amplify function template

    is plugin for amplify cl i • util plugi n • Plugin name is named functionTemplate • Template meta information is defined in functionTemplate of amplify-plugin.json • Implements functionTemplateContributo rFactory function
  5. Authoring a custom function template The specification of custom function

    template plugi n • Generate AppSync Lambda Resolve r • Supported Lambda runtime is Node.j s • User can select GraphQL fields in schema.graphql to associate resolver
  6. Authoring a custom function template Implementation step s 1.Run amplify

    plugin ini t 2.Edit amplify-plugin.jso n 3.Implements functionTemplateContributorFactory functio n 4.Implements source code templates with EJS templat e 5.Implements additional questions for user (Optional)
  7. Run amplify plugin init • Run amplify plugin init •

    Input name of the custom function template plugin (ex: amplify-appsync- resolver-nodejs-function-template-provider ) • Select util plugin as typ e • Clear all selections for event handle
  8. Edit amplify-plugin.json • Set the name attribute to functionTemplate •

    Define the functionTemplate attribut e • The conditions attribute defines the conditions to which the template applie s • The templates attribute defines a list of user-selectable templates on the CLI { "name": "functionTemplate", "type": “util", "commands": [], "eventHandlers": [], "functionTemplate": { "conditions": { "provider": "awscloudformation", "services": ["Lambda"], "runtime": "nodejs" }, "templates": [ { "name": "AppSync Lambda Resolver", "value": "resolver" } ] } }
  9. Implements functionTemplateContributorFactory function • Implement a function named functionTemplateContributor Factory

    in index.ts • functionTemplateContributor Factory function takes a context as an argument and returns an object with contribute functio n • contribute function is a function that takes a TemplateContributionRequest as an argument and returns a Partial <FunctionParameters> export const functionTemplateContributorFactory: FunctionTemplateContributorFactory = (context) => { return { contribute: (request) => { switch (request.selection) { case 'resolver': { const resolvers = await askGraphQLFieldsQuestions(context); const files = fs.readdirSync(pathToTemplateFiles); return Promise.resolve({ functionTemplate: { sourceRoot: pathToTemplateFiles, sourceFiles: files, defaultEditorFile: path.join('src', 'index.js'), destMap: getDstMap(files), parameters: { resolvers } }, }); } default: { throw new Error(`Unknown template selection [${request.selection}]`); } } } } };
  10. Implements source code templates with EJS template • Templates can

    be written in EJ S • In the EJS template, the return value of the contribute function can be accessed with the props variabl e • This can be used to query the user and reflect the entered value in a file that outputs /** * Using this as the entry point, you can use a single function to handle many resolvers. */ const resolvers = {<% for(var resolver of props.functionTemplate.parameters.resolvers) { %> <%= resolver.name %>: {<% for(var fieldResolver of resolver.fieldResolvers) { %> <%= fieldResolver.name %>: ctx => { // Add your code here },<% } %> },<% } %> } exports.handler = async (event) => { const typeHandler = resolvers[event.typeName]; if (typeHandler) { const resolver = typeHandler[event.fieldName]; if (resolver) { return await resolver(event); } } throw new Error("Resolver not found."); };