$30 off During Our Annual Pro Sale. View Details »

Using custom function template with AWS Amplify

Using custom function template with AWS Amplify

MURAKAMI Masahiko

November 20, 2021
Tweet

More Decks by MURAKAMI Masahiko

Other Decks in Programming

Transcript

  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."); };