{"id":13532731,"url":"https://github.com/amazon-archives/aws-serverless-appsync-loyalty","last_synced_at":"2025-04-01T21:30:56.536Z","repository":{"id":141667525,"uuid":"139356500","full_name":"amazon-archives/aws-serverless-appsync-loyalty","owner":"amazon-archives","description":"Unicorn Loyalty: E-Commerce Serverless GraphQL Loyalty Sample App","archived":true,"fork":false,"pushed_at":"2020-02-07T21:56:06.000Z","size":3142,"stargazers_count":115,"open_issues_count":0,"forks_count":37,"subscribers_count":14,"default_branch":"master","last_synced_at":"2024-05-21T13:57:50.246Z","etag":null,"topics":["amplify","appsync","aws","e-commerce-example","graphql","lambda","serverless"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit-0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/amazon-archives.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-07-01T19:35:26.000Z","updated_at":"2024-06-06T05:30:22.557Z","dependencies_parsed_at":"2024-06-12T14:31:39.766Z","dependency_job_id":null,"html_url":"https://github.com/amazon-archives/aws-serverless-appsync-loyalty","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/amazon-archives%2Faws-serverless-appsync-loyalty","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/amazon-archives%2Faws-serverless-appsync-loyalty/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/amazon-archives%2Faws-serverless-appsync-loyalty/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/amazon-archives%2Faws-serverless-appsync-loyalty/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/amazon-archives","download_url":"https://codeload.github.com/amazon-archives/aws-serverless-appsync-loyalty/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246712953,"owners_count":20821824,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["amplify","appsync","aws","e-commerce-example","graphql","lambda","serverless"],"created_at":"2024-08-01T07:01:13.318Z","updated_at":"2025-04-01T21:30:54.159Z","avatar_url":"https://github.com/amazon-archives.png","language":"JavaScript","funding_links":[],"categories":["Example Projects"],"sub_categories":[],"readme":"## Unicorn Loyalty: E-Commerce Serverless GraphQL Loyalty Sample App\n\nUnicorn Loyalty is a new startup that provides fantastic unicorns for customers. The business just started and it's giving away 1000 Unicoin Points for new customers to purchase the unicorns available on inventory.\n\n(Live Coding walk-through video covering Lambda and AppSync manual setup available on https://www.youtube.com/watch?v=WOQIqRVzkas or https://www.twitch.tv/videos/288401222)\n\n### Behind the Scenes\n\n![Architecture](img/00.png)\n\n* AWS AppSync\n* AWS Lambda\n* Amazon DynamoDB\n* Amazon Cognito User Pools\n* Amazon Pinpoint\n* No Servers!\n\n#### Prerequisites\n\n* [AWS Account](https://aws.amazon.com/mobile/details) with appropriate permissions to create the related resources\n* [NodeJS v8.10+](https://nodejs.org/en/download/) with [NPM](https://docs.npmjs.com/getting-started/installing-node)\n* [AWS Mobile CLI](https://github.com/aws/awsmobile-cli) `(npm install -g awsmobile-cli)`\n* [AWS Amplify](https://aws.github.io/aws-amplify/media/react_guide) `(npm install -g aws-amplify-react)`\n* [create-react-app](https://github.com/facebook/create-react-app) `(npm install -g create-react-app)`\n\n#### Optional\n\n* [AWS Cloud9](https://aws.amazon.com/cloud9/) :\nWe assume you are using Cloud9 to build this application. You can optionally choose to use any IDE/Text Editor such as Atom or VS Code, in that case you should use the [AWS SAM CLI](https://github.com/awslabs/aws-sam-cli) to deploy Lambda and the DynamoDB tables.\n\n### Initial Setup - Mobile CLI and Amplify\n\nCreate a Cloud 9 environment and execute:\n\n    $ create-react-app unicorn-loyalty\n    $ cd unicorn-loyalty\n\n\nInstall and use the latest LTS Node version:\n\n\n    $ nvm i v8\n\n\nSet up your AWS resources with the AWS Mobile CLI:\n\n\n    $ awsmobile init\n\n\nChose the default options, make sure you are logged in with a user that has administrator access and click the resulting link to create an IAM user for the Mobile CLI by selecting OPEN: \n\n![Mobile CLI Setup](img/01.png)\n\nFollow the steps in the IAM Console with default options then use the generated credentials to configure the access in the Mobile CLI:\n\n![Mobile CLI Permissions](img/02.png)\n\nNow let's add the features we need for our application (User Sign In, Analytics, Hosting and AppSync):\n\n![Mobile CLI Features](img/03.png)\n\nExecute the following command to commit the changes:\n\n    $ awsmobile push\n\nTo test if everything is working, open App.js and let's add 4 extra lines of code to add AuthN/Z with MFA (withAuthenticator HOC). Replace the existing code with:\n\n```javascript\nimport React, { Component } from 'react';\nimport logo from './logo.svg';\nimport './App.css';\nimport Amplify from 'aws-amplify';\nimport { withAuthenticator } from 'aws-amplify-react';\nimport aws_exports from './aws-exports'; // specify the location of aws-exports.js file on your project\nAmplify.configure(aws_exports);\n\nclass App extends Component {\n  render() {\n    return (\n      \u003cdiv className=\"App\"\u003e\n        \u003cheader className=\"App-header\"\u003e\n          \u003cimg src={logo} className=\"App-logo\" alt=\"logo\" /\u003e\n          \u003ch1 className=\"App-title\"\u003eWelcome to React\u003c/h1\u003e\n        \u003c/header\u003e\n        \u003cp className=\"App-intro\"\u003e\n          To get started, edit \u003ccode\u003esrc/App.js\u003c/code\u003e and save to reload.\n        \u003c/p\u003e\n      \u003c/div\u003e\n    );\n  }\n}\n\nexport default withAuthenticator(App, { includeGreetings: true });\n```\nNow execute:\n\n\n    $ awsmobile run\n\n\nThen click on PREVIEW -\u003e PREVIEW RUNNING APPLICATION on Cloud9 and sign up a user:\n\n![Mobile CLI Features](img/04.png)\n\nDownload all files from the Github repo. Upload them to your Cloud9 workspace (FILE -\u003e UPLOAD LOCAL FILES), overwriting the files in the local React app folder:\n\n![Uploading Files](img/05.png)\n\n### Lambda Setup\n\nFrom Cloud9 select the AWS Resources tab on the right, you'll find a local Lambda funcion under the ```sam``` folder called ```UnicornLoyalty```. Right click and select EDIT CONFIG to check the related SAM template and EDIT FUNCTION to check the Lambda code:\n\n![Lambda SAM Config](img/06.png)\n\nBy default the 1000 Unicoins give away special is valid until the last day of 2018. Edit the expiry date accordingly if you want to modify the deadline:\n\n```javascript\nlet expiry = new Date('2018.12.31').getTime() / 1000; \n```\n\nOn the same menu click DEPLOY (or execute ```sam package/deploy``` with the SAM CLI it you're not on Cloud9). The SAM Template will deploy a Lambda function and 3 DynamoDB tables. Lambda will interact directly with the Users table by detecting newly registered users to make sure they will only get the 1000 Unicoin Points special before the expiry date as well as manage and update the user unicoins/points balance when a order is placed. The other tables will be used directly by AppSync.\n\n### AppSync Setup\n\nThe Mobile CLI creates a sample Event API on AppSync by default. We wont use that. Go to the AppSync console and paste the contents of the file ```appsync/schema.graphql``` in the SCHEMA setion:\n\n![GraphQL Schema](img/07.png)\n\nGo to DATA SOURCES, delete the 2 tables from the sample. Now create 3 data sources as follows, pointing to the Items and Orders tables and the Lambda function created earlier :\n\n![AppSync Data Sources](img/08.png)\n\nBack to Cloud9, execute the following command to retrieve the AppSync changes:\n\n    $ awsmobile pull\n\nGo to the folder ```awsmobilejs/backend/appsync``` and delete the file ```resolvers.json``` and the folder ```resolver-mappings```.\n\nNow go to the folder ```appsync``` in the root of the application directory and copy the file ```resolvers.json``` and the folder ```resolver-mappings``` to the previous folder ```awsmobilejs/backend/appsync```, replacing the deleted files.\n\nNext step is to configure AppSync authentication. Execute the following command and select the options:\n\n\n    $ awsmobile appsync configure\n\n    ? Please specify the auth type:  AMAZON_COGNITO_USER_POOLS\n    ? user pool id:  \u003cUser Pools ID\u003e\n    ? region:  \u003cRegion\u003e\n    ? default action:  ALLOW\n\n\nExecute the following command to commit the changes:\n\n\n    $ awsmobile push\n\n\n### Creating Some Unicorns\n\nOpen the file ```src/aws-exports.js``` generated by the Mobile CLI and copy the value of the key \"aws_user_pools_web_client_id\"to retrieve the App Client ID the Cognito User Pools is using to authenticate AppSync calls.\n\nGo to the AppSync console and select the QUERY section. Click LOGIN WITH USER POOLS, use the client ID you just retrieved from ```aws-exports.js``` and the credentials from the user you signed up earlier. You'll also need to provide a MFA code.\n\nExecute the following GraphQL operation (mutation) to create your first Unicorn:\n\n```javascript\nmutation {\n  addInventory(itemDescription: \"Amazing Unicorn\", price: 50){\n    itemId\n    itemDescription\n    price\n  }\n}\n```\n\nCreate as many Unicorns as you'd like by changing the values. Going to the DynamoDB console, you can confirm the Unicorns were created successfully:\n\n![Unicorns on DynamoDB](img/09.png)\n\n### Welcome to the Unicorn Loyalty Shop\n\nBack to Cloud9 execute:\n\n\n    $ awsmobile run\n\n(In case of errors or missing packages, you might need to run ```npm install``` and try again)\n\nThen click on PREVIEW -\u003e PREVIEW RUNNING APPLICATION to access the Unicorn Loyalty App:\n\n![Unicorn Loyalty Shop - Preview](img/10.png)\n\nFinally you can publish to CloudFront and S3 with a single command:\n\n    $ awsmobile publish\n\nIt will automatically make the Unicorn Loyalty app available in a powerful and reliable global content delivery network backed by a S3 website:\n\n![Unicorn Loyalty Shop - Prod](img/13.png)\n\nYou can get Analitycs about usage and revenue from Amazon Pinpoint, all thanks to a couple of lines of code required by the AWS Amplify Analytics component and the to the Pinpoint Project AWS Mobile CLI creates by default:\n\n```javascript\nAnalytics.record({\n    name: 'unicornsPurchase', \n    attributes: {}, \n    metrics: { totalOrder: order.totalOrder }\n});\nAnalytics.record('_monetization.purchase', {\n    _currency: 'USD',\n    _product_id: order.itemId,\n    }, {\n    _item_price: order.unitPrice,\n    _quantity: order.count,\n})\n```\n\n* Usage Data:\n![Unicorn Analytics](img/11.png)\n\n* Revenue Data:\n![Unicorn Analytics](img/12.png)\n\n## Feel like a challenge? What's next?\n\nWe added the backend logic to get all orders from the current user:\n\n```graphql\nquery {\n  getMyOrders{\n    orderId\n    itemId\n    count\n    date\n    totalOrder\n  }\n}\n```\n\nAlternatively, you can get the same result using the relation between the User type (Users Table) and the Order type (Orders Table) by querying the User ID:\n\n```graphql\nquery {\n  getMe(userId:\"\u003cUser ID Here\u003e\"){\n    orders{\n        orderId\n    }\n  }\n}\n```\n\nWe also added the backend logic to get the items in a specific order by querying the Order ID:\n\n```graphql\nquery {\n  getOrder(orderId:\"\u003cOrder ID Here\u003e\"){\n    orderId\n    itemId\n    count\n    date\n    totalOrder\n  }\n}\n```\n\nUsing AWS Amplify implement a new feature to the Unicorn Loyalty app so users can get information on all the orders they placed as well as Unicorns that were purchased in a previous order. Bonus points if implemented with the built-in pagination support.\n\nGo Build with Serverless GraphQL!\n\n## License Summary\n\nThis sample code is made available under a modified MIT license. See the LICENSE file.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Famazon-archives%2Faws-serverless-appsync-loyalty","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Famazon-archives%2Faws-serverless-appsync-loyalty","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Famazon-archives%2Faws-serverless-appsync-loyalty/lists"}