{"id":13432573,"url":"https://github.com/dabit3/graphql-recipes","last_synced_at":"2025-11-17T15:21:11.519Z","repository":{"id":73190966,"uuid":"193460863","full_name":"dabit3/graphql-recipes","owner":"dabit3","description":"A list of GraphQL recipes that, when used with the Amplify CLI, will deploy an entire AWS AppSync GraphQL backend.","archived":false,"fork":false,"pushed_at":"2020-07-06T14:16:45.000Z","size":463,"stargazers_count":156,"open_issues_count":4,"forks_count":17,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-10-09T09:58:58.648Z","etag":null,"topics":["apis","aws","aws-amplify","aws-appsync","dynamodb","graphql","serverless"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dabit3.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2019-06-24T08:00:14.000Z","updated_at":"2025-09-09T18:54:26.000Z","dependencies_parsed_at":null,"dependency_job_id":"4c326cb9-b1fd-4b5f-81f2-e1004b8e26fe","html_url":"https://github.com/dabit3/graphql-recipes","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/dabit3/graphql-recipes","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dabit3%2Fgraphql-recipes","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dabit3%2Fgraphql-recipes/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dabit3%2Fgraphql-recipes/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dabit3%2Fgraphql-recipes/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dabit3","download_url":"https://codeload.github.com/dabit3/graphql-recipes/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dabit3%2Fgraphql-recipes/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":284907221,"owners_count":27082806,"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","status":"online","status_checked_at":"2025-11-17T02:00:06.431Z","response_time":55,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["apis","aws","aws-amplify","aws-appsync","dynamodb","graphql","serverless"],"created_at":"2024-07-31T02:01:13.594Z","updated_at":"2025-11-17T15:21:11.497Z","avatar_url":"https://github.com/dabit3.png","language":null,"funding_links":[],"categories":["Others"],"sub_categories":[],"readme":"# GraphQL App Recipes\n\n\u003e This repo is an evolving work in progress. As I add more recipes, I will break these out into individual full-stack applications including the front end and adding additional examples. If you have any ideas, please feel free to either contribute or submit an issue!\n\n![](header.jpg)\n\nThis repo goes along with the [tutorial on building AWS AppSync APIs using the Amplify GraphQL Transform library](https://dev.to/open-graphql/graphql-recipes-building-apis-with-graphql-transform-3jp0).\n\nTo learn more about GraphQL Transform library, check out [the documentation](https://aws-amplify.github.io/docs/cli-toolchain/graphql?sdk=js).\n\nTo learn more about building full stack serverless applications with GraphQL and AWS Amplify, check out my post [Infrastructure as Code in the Era of GraphQL and Full Stack Serverless](https://dev.to/dabit3/infrastructure-as-code-in-the-era-of-graphql-and-full-stack-serverless-11bc).\n\n1. [Todo App](#todo-app)\n2. [Events App](#event-app)\n3. [Chat App](#chat-app)\n3. [Multi-user Chat App](#multiuser-chat-app)\n4. [E Commerce App](#e-commerce-app)\n5. [WhatsApp Clone](#whatsapp-clone)\n6. [Reddit Clone](#reddit-clone)\n7. [Conference App](#conference-app)\n8. [Instagram Clone](#instagram-clone)\n9. [Giphy Clone](#giphy-clone)\n\n\u003e Some applications may require additional custom authorization logic for certain subscriptions that you may not want accessible to all users. To learn more, check out the documentation [here](https://docs.aws.amazon.com/appsync/latest/devguide/security-authorization-use-cases.html).\n\n## Todo App\n\nTo deploy this app, use the following steps:\n\n1. Create the Amplify project in your app\n\n```sh\namplify init\n```\n\n2. Add the GraphQL API\n\n```sh\namplify add api\n```\n\nUse the following schema\n\n```graphql\ntype Todo @model {\n  id: ID!\n  name: String!\n  description: String\n}\n```\n\n3. Deploy the resources\n\n```sh\namplify push\n```\n\n## Event App\n\nTo deploy this app, use the following steps:\n\n1. Create the Amplify project in your app\n\n```sh\namplify init\n```\n\n2. Add authentication\n\n```sh\namplify add auth\n```\n\n3. Add the GraphQL API\n\n```sh\namplify add api\n```\n\nUse the following schema\n\n```graphql\ntype Event @model\n  @key(name: \"itemType\", fields: [\"itemType\", \"time\"], queryField: \"eventsByDate\")\n  @auth(rules: [\n    { allow: groups, groups: [\"Admin\"] },\n    { allow: public, operations: [read] },\n    { allow: private, operations: [read] }\n  ]) {\n    id: ID!\n    name: String!\n    description: String\n    time: String!\n    itemType: String!\n    comments: [Comment] @connection #optional comments field\n}\n\n# Optional Comment type\ntype Comment @model\n  @auth(rules: [\n    { allow: owner, ownerField: \"author\" },\n    { allow: public, operations: [read] },\n    { allow: private, operations: [read] }\n  ]) {\n  id: ID!\n  message: String!\n  author: String\n}\n```\n\n4. Deploy the resources\n\n```sh\namplify push\n```\n\n## Chat app\n\nTo deploy this app, use the following steps:\n\n1. Create the Amplify project in your app\n\n```sh\namplify init\n```\n\n2. Add the GraphQL API\n\n```sh\namplify add api\n```\n\nUse the following GraphQL Schema:\n\n```graphql\ntype Conversation @model {\n  id: ID!\n  name: String\n  messages: [Message] @connection(keyName: \"messagesByConversationId\", fields: [\"id\"])\n  createdAt: String\n  updatedAt: String\n}\n\ntype Message\n  @key(name: \"messagesByConversationId\", fields: [\"conversationId\"])\n  @model(subscriptions: null, queries: null) {\n  id: ID!\n  conversationId: ID!\n  content: String!\n  conversation: Conversation @connection(fields: [\"conversationId\"])\n  createdAt: String\n}\n```\n\n## Multi-user Chat App\n\nTo deploy this app, use the following steps:\n\n1. Create the Amplify project in your app\n\n```sh\namplify init\n```\n\n2. Add authentication\n\n```sh\namplify add auth\n```\n\n3. Add the GraphQL API\n\n```sh\namplify add api\n```\n\nUse the following GraphQL Schema:\n\n```graphql\ntype User\n  @key(fields: [\"userId\"])\n  @model(subscriptions: null)\n  @auth(rules: [\n    { allow: owner, ownerField: \"userId\" }\n  ]) {\n  userId: ID!\n  conversations: [ConvoLink] @connection(keyName: \"conversationsByUserId\", fields: [\"userId\"])\n  messages: [Message] @connection(keyName: \"messagesByUserId\", fields: [\"userId\"])\n  createdAt: String\n  updatedAt: String\n}\n\ntype Conversation\n  @model(subscriptions: null)\n  @auth(rules: [{ allow: owner, ownerField: \"members\" }]) {\n  id: ID!\n  messages: [Message] @connection(keyName: \"messagesByConversationId\", fields: [\"id\"])\n  associated: [ConvoLink] @connection(keyName: \"convoLinksByConversationId\", fields: [\"id\"])\n  members: [String!]!\n  createdAt: String\n  updatedAt: String\n}\n\ntype Message\n  @key(name: \"messagesByConversationId\", fields: [\"conversationId\"])\n  @key(name: \"messagesByUserId\", fields: [\"userId\"])\n  @model(subscriptions: null, queries: null) {\n  id: ID!\n  userId: ID!\n  conversationId: ID!\n  author: User @connection(fields: [\"userId\"])\n  content: String!\n  conversation: Conversation @connection(fields: [\"conversationId\"])\n  createdAt: String\n  updatedAt: String\n}\n\ntype ConvoLink\n  @key(name: \"convoLinksByConversationId\", fields: [\"conversationId\"])\n  @key(name: \"conversationsByUserId\", fields: [\"userId\"])\n  @model(\n    mutations: { create: \"createConvoLink\", update: \"updateConvoLink\" }\n    queries: null\n    subscriptions: null\n  ) {\n  id: ID!\n  userId: ID!\n  conversationId: ID!\n  user: User @connection(fields: [\"userId\"])\n  conversation: Conversation @connection(fields: [\"conversationId\"])\n  createdAt: String\n  updatedAt: String\n}\n\ntype Subscription {\n  onCreateConvoLink(userId: ID): ConvoLink\n    @aws_subscribe(mutations: [\"createConvoLink\"])\n  onCreateMessage(conversationId: ID): Message\n    @aws_subscribe(mutations: [\"createMessage\"])\n}\n```\n\n4. Deploy the resources\n\n```sh\namplify push\n```\n\n## E-commerce App\n\nTo deploy this app, use the following steps:\n\n1. Create the Amplify project in your app\n\n```sh\namplify init\n```\n\n2. Add authentication\n\n```sh\namplify add auth\n```\n\n3. Add the GraphQL API\n\n```sh\namplify add api\n```\n\nUse the following GraphQL schema:\n\n```graphql\n# Products - Orders - Customers\n\ntype Customer @model(subscriptions: null)\n  @auth(rules: [\n    { allow: owner },\n    { allow: groups, groups: [\"Admin\"] }\n  ]) {\n  id: ID!\n  name: String!\n  email: String!\n  address: String\n  orders: [Order] @connection(keyName: \"byCustomerId\", fields: [\"id\"])\n}\n\ntype Product @model(subscriptions: null)\n  @auth(rules: [\n    { allow: groups, groups: [\"Admin\"] },\n    { allow: public, operations: [read] },\n    { allow: private, operations: [read] }\n  ]) {\n  id: ID!\n  name: String!\n  description: String\n  price: Float!\n  image: String\n}\n\ntype Order @model(subscriptions: null)\n  @key(name: \"byCustomerId\", fields: [\"customerId\", \"createdAt\"], queryField: \"ordersByCustomerId\")\n  @auth(rules: [\n   { allow: owner },\n   { allow: groups, groups: [\"Admin\"] }\n  ]) {\n  id: ID!\n  customerId: ID!\n  total: Float\n  subtotal: Float\n  tax: Float\n  createdAt: String!\n  customer: Customer @connection(fields: [\"customerId\"])\n  lineItems: [LineItem] @connection(keyName: \"byOrderId\", fields: [\"id\"])\n}\n\ntype LineItem @model(subscriptions: null)\n  @key(name: \"byOrderId\", fields: [\"orderId\"])\n  @auth(rules: [\n   { allow: owner },\n   { allow: groups, groups: [\"Admin\"] }\n  ]) {\n  id: ID!\n  orderId: ID!\n  productId: ID!\n  qty: Int\n  order: Order @connection(fields: [\"orderId\"])\n  product: Product @connection(fields: [\"productId\"])\n  description: String\n  price: Float\n  total: Float\n}\n```\n\n4. Add Storage (S3)\n\n```sh\namplify add storage\n\n? Please select from one of the below mentioned services (Use arrow keys): Content (Images, audio, video, etc.)\n? Please provide a friendly name for your resource that will be used to label this category in the project: imagestorage\n? Please provide bucket name: \u003cUNIQUE_BUCKET_NAME\u003e\n? Who should have access: Auth and Guest users\n? What kind of access do you want for Authenticated users? create/update, read, delete\n? What kind of access do you want for Guest users? read\n```\n\n5. Deploy the resources\n\n```sh\namplify push\n```\n\n## Whatsapp Clone\n\nTo deploy this app, use the following steps:\n\n1. Create the Amplify project in your app\n\n```sh\namplify init\n```\n\n2. Add authentication\n\n```sh\namplify add auth\n```\n\n3. Add the GraphQL API\n\n```sh\namplify add api\n```\n\nUse the following GraphQL schema:\n\n```graphql\ntype User\n  @key(fields: [\"userId\"])\n  @model(subscriptions: null)\n  @auth(rules: [\n    { allow: owner, ownerField: \"userId\" }\n  ]) {\n  userId: ID!\n  avatar: String\n  conversations: [ConvoLink] @connection(keyName: \"conversationsByUserId\", fields: [\"userId\"])\n  messages: [Message] @connection(keyName: \"messagesByUserId\", fields: [\"userId\"])\n  createdAt: String\n  updatedAt: String\n}\n\ntype Conversation\n  @model(subscriptions: null)\n  @auth(rules: [{ allow: owner, ownerField: \"members\" }]) {\n  id: ID!\n  messages: [Message] @connection(keyName: \"messagesByConversationId\", fields: [\"id\"])\n  associated: [ConvoLink] @connection(keyName: \"convoLinksByConversationId\", fields: [\"id\"])\n  members: [String!]!\n  createdAt: String\n  updatedAt: String\n}\n\ntype Message\n  @key(name: \"messagesByConversationId\", fields: [\"conversationId\"])\n  @key(name: \"messagesByUserId\", fields: [\"userId\"])\n  @model(subscriptions: null, queries: null) {\n  id: ID!\n  userId: ID!\n  conversationId: ID!\n  author: User @connection(fields: [\"userId\"])\n  content: String!\n  image: String\n  conversation: Conversation @connection(fields: [\"conversationId\"])\n  createdAt: String\n  updatedAt: String\n}\n\ntype ConvoLink\n  @key(name: \"convoLinksByConversationId\", fields: [\"conversationId\"])\n  @key(name: \"conversationsByUserId\", fields: [\"userId\"])\n  @model(\n    mutations: { create: \"createConvoLink\", update: \"updateConvoLink\" }\n    queries: null\n    subscriptions: null\n  ) {\n  id: ID!\n  userId: ID!\n  conversationId: ID!\n  user: User @connection(fields: [\"userId\"])\n  conversation: Conversation @connection(fields: [\"conversationId\"])\n  createdAt: String\n  updatedAt: String\n}\n\ntype Subscription {\n  onCreateConvoLink(userId: ID): ConvoLink\n    @aws_subscribe(mutations: [\"createConvoLink\"])\n  onCreateMessage(conversationId: ID): Message\n    @aws_subscribe(mutations: [\"createMessage\"])\n}\n```\n\n4. Add Storage (S3)\n\n```sh\namplify add storage\n\n? Please select from one of the below mentioned services (Use arrow keys): Content (Images, audio, video, etc.)\n? Please provide a friendly name for your resource that will be used to label this category in the project: imagestorage\n? Please provide bucket name: \u003cUNIQUE_BUCKET_NAME\u003e\n? Who should have access: Auth and Guest users\n? What kind of access do you want for Authenticated users? create/update, read, delete\n? What kind of access do you want for Guest users? read\n```\n\n5. Deploy the resources\n\n```sh\namplify push\n```\n\n## Reddit clone\n\nTo deploy this app, use the following steps:\n\n1. Create the Amplify project in your app\n\n```sh\namplify init\n```\n\n2. Add authentication\n\n```sh\namplify add auth\n```\n\n3. Add the GraphQL API\n\n```sh\namplify add api\n```\n\nUse the following GraphQL Schema:\n\n```graphql\ntype User @model(subscriptions: null)\n  @key(fields: [\"userId\"])\n  @auth(rules: [\n    { allow: owner, ownerField: \"userId\" }\n  ]) {\n  userId: ID!\n  posts: [Post] @connection(keyName: \"postByUser\", fields: [\"userId\"])\n  createdAt: String\n  updatedAt: String\n}\n\ntype Post @model\n  @key(name: \"postByUser\", fields: [\"authorId\", \"createdAt\"])\n  @auth(rules: [\n    { allow: owner, ownerField: \"authorId\" },\n    { allow: public, operations: [read] },\n    { allow: private, operations: [read] }\n  ]) {\n  id: ID!\n  authorId: ID!\n  author: User @connection(fields: [\"authorId\"])\n  postContent: String\n  postImage: String\n  comments: [Comment] @connection(keyName: \"commentsByPostId\", fields: [\"id\"])\n  votes: [PostVote] @connection(keyName: \"votesByPostId\", fields: [\"id\"])\n  createdAt: String\n  voteCount: Int\n}\n\ntype Comment @model\n  @key(name: \"commentsByPostId\", fields: [\"postId\"])\n  @auth(rules: [\n    { allow: owner, ownerField: \"authorId\" },\n    { allow: public, operations: [read] },\n    { allow: private, operations: [read] }\n  ]) {\n  id: ID!\n  authorId: ID!\n  postId: ID!\n  text: String!\n  author: User @connection(fields: [\"authorId\"])\n  votes: [CommentVote] @connection(keyName: \"votesByCommentId\", fields: [\"id\"])\n  post: Post @connection(fields: [\"postId\"])\n  voteCount: Int\n}\n\ntype PostVote @model\n  @auth(rules: [\n    { allow: owner, ownerField: \"userId\"},\n    { allow: public, operations: [read] },\n    { allow: private, operations: [read] }\n  ])\n  @key(name: \"votesByPostId\", fields: [\"postId\"]) {\n  id: ID!\n  postId: ID!\n  userId: ID!\n  post: Post @connection(fields: [\"postId\"])\n  createdAt: String!\n  vote: VoteType\n}\n\ntype CommentVote @model\n  @auth(rules: [\n    { allow: owner, ownerField: \"userId\"},\n    { allow: public, operations: [read] },\n    { allow: private, operations: [read] }\n  ])\n  @key(name: \"votesByCommentId\", fields: [\"commentId\"]) {\n  id: ID!\n  userId: ID!\n  commentId: ID!\n  comment: Comment @connection(fields: [\"commentId\"])\n  createdAt: String!\n  vote: VoteType\n}\n\ninput VoteInput {\n  type: VoteType!\n  id: ID!\n}\n\nenum VoteType {\n  up\n  down\n}\n```\n\n#### Custom resolver for votes\n\nIn the request mapping template,\n\n```\n# Set the vote ID as a combination of the postId and the user's userId.\n#set($itemId = \"$context.identity.username#$context.args.postId\")\n$util.qr($context.args.input.put(\"id\", $util.defaultIfNull($ctx.args.input.id, $itemId)))\n\n# delete or comment out the conditional expression code that does not allow the vote to be overridden:\n#set( $condition = {\n  \"expression\": \"attribute_not_exists(#id)\",\n  \"expressionNames\": {\n      \"#id\": \"id\"\n  }\n})\n```\n\n4. Add Storage (S3)\n\n```sh\namplify add storage\n\n? Please select from one of the below mentioned services (Use arrow keys): Content (Images, audio, video, etc.)\n? Please provide a friendly name for your resource that will be used to label this category in the project: imagestorage\n? Please provide bucket name: \u003cUNIQUE_BUCKET_NAME\u003e\n? Who should have access: Auth and Guest users\n? What kind of access do you want for Authenticated users? create/update, read, delete\n? What kind of access do you want for Guest users? read\n```\n\n5. Deploy the resources\n\n```sh\namplify push\n```\n\n## Conference App\n\nTo deploy this app, use the following steps:\n\n1. Create the Amplify project in your app\n\n```sh\namplify init\n```\n\n2. Add authentication\n\n```sh\namplify add auth\n```\n\n3. Add the GraphQL API\n\n```sh\namplify add api\n```\n\nUse the following GraphQL Schema:\n\n```graphql\ntype Talk @model\n  @auth(rules: [\n    { allow: groups, groups: [\"Admin\"] },\n    { allow: public, operations: [read] },\n    { allow: private, operations: [read] }\n  ]) {\n  id: ID!\n  name: String!\n  speakerName: String!\n  speakerBio: String!\n  time: String\n  timeStamp: String\n  date: String\n  location: String\n  summary: String!\n  twitter: String\n  github: String\n  speakerAvatar: String\n  comments: [Comment] @connection(keyName: \"commentsByTalkId\", fields: [\"id\"])\n}\n\ntype Comment @model\n  @key(name: \"commentsByTalkId\", fields: [\"talkId\"])\n  @auth(rules: [\n    { allow: owner, ownerField: \"authorId\" },\n    { allow: public, operations: [read] },\n    { allow: private, operations: [read] }\n  ])\n{\n  id: ID!\n  talkId: ID!\n  talk: Talk @connection(fields: [\"talkId\"])\n  message: String\n  createdAt: String\n  authorId: ID!\n  deviceId: ID\n}\n\ntype Report @model\n  @auth(rules: [\n    { allow: owner, operations: [create, update, delete] },\n    { allow: groups, groups: [\"Admin\"] }\n  ])\n  {\n  id: ID!\n  commentId: ID!\n  comment: String!\n  talkTitle: String!\n  deviceId: ID\n}\n\ntype ModelCommentConnection {\n  items: [Comment]\n  nextToken: String\n}\n\ntype Query {\n  listCommentsByTalkId(talkId: ID!): ModelCommentConnection\n}\n\ntype Subscription {\n  onCreateCommentWithId(talkId: ID!): Comment\n        @aws_subscribe(mutations: [\"createComment\"])\n}\n```\n\n4. Deploy the resources\n\n```sh\namplify push\n```\n\n## Instagram Clone\n\nTo deploy this app, use the following steps:\n\n1. Create the Amplify project in your app\n\n```sh\namplify init\n```\n\n2. Add authentication\n\n```sh\namplify add auth\n```\n\n3. Add the GraphQL API\n\n```sh\namplify add api\n```\n\nUse the following GraphQL Schema:\n\n```graphql\ntype User @model(subscriptions: null)\n  @key(fields: [\"userId\"])\n  @auth(rules: [\n    { allow: owner, ownerField: \"userId\" },\n    { allow: private, operations: [read] }\n    ]) {\n  userId: ID!\n  posts: [Post] @connection(keyName: \"postsByUserId\", fields: [\"userId\"])\n  createdAt: String\n  updatedAt: String\n  following: [Following] @connection(keyName: \"followingByUserId\", fields: [\"userId\"])\n}\n\ntype Post @model\n  @key(name: \"postsByUserId\", fields: [\"authorId\"])\n  @auth(rules: [\n    { allow: owner ownerField: \"authorId\" },\n    { allow: public, operations: [read] },\n    { allow: private, operations: [read] }\n  ]) {\n  id: ID!\n  authorId: ID!\n  content: String!\n  postImage: String\n  author: User @connection(fields: [\"authorId\"])\n  comments: [Comment] @connection(keyName: \"commentsByPostId\", fields: [\"id\"])\n  likes: [PostLike] @connection(keyName: \"postLikesByPostId\", fields: [\"id\"])\n}\n\ntype Comment @model\n  @key(name: \"commentsByPostId\", fields: [\"postId\"])\n  @auth(rules: [\n    { allow: owner, ownerField: \"authorId\" },\n    { allow: public, operations: [read] },\n    { allow: private, operations: [read] }\n  ]) {\n  id: ID!\n  postId: ID!\n  authorId: ID!\n  text: String!\n  likes: [CommentLike] @connection(keyName: \"commentLikesByCommentId\", fields: [\"id\"])\n  author: User @connection(fields: [\"authorId\"])\n  post: Post @connection(fields: [\"postId\"])\n}\n\ntype PostLike @model\n  @auth(rules: [\n    { allow: owner, ownerField: \"userId\" },\n    { allow: public, operations: [read] },\n    { allow: private, operations: [read] }\n  ])\n  @key(name: \"postLikesByPostId\", fields: [\"postId\"])\n  @key(name: \"postLikesByUser\", fields: [\"userId\", \"createdAt\"], queryField: \"likesByUser\") {\n  id: ID!\n  postId: ID!\n  userId: ID!\n  user: User @connection(fields: [\"userId\"])\n  post: Post @connection(fields: [\"postId\"])\n  createdAt: String!\n}\n\ntype CommentLike @model\n  @auth(rules: [\n    { allow: owner, ownerField: \"userId\" },\n    { allow: public, operations: [read] },\n    { allow: private, operations: [read] }\n  ])\n  @key(name: \"commentLikesByCommentId\", fields: [\"commentId\"])\n  @key(name: \"commentLikesByUser\", fields: [\"userId\", \"createdAt\"], queryField: \"likesByUser\") {\n  id: ID!\n  userId: ID!\n  postId: ID!\n  commentId: ID!\n  user: User @connection(fields: [\"userId\"])\n  post: Post @connection(fields: [\"postId\"])\n  createdAt: String!\n}\n\ntype Following @model\n  @auth(rules: [\n    { allow: owner, ownerField: \"followerId\" },\n    { allow: public, operations: [read] },\n    { allow: private, operations: [read] }\n  ])\n  @key(name: \"followingByUserId\", fields: [\"followerId\"]) {\n  id: ID\n  followerId: ID!\n  followingId: ID!\n  follower: User @connection(fields: [\"followerId\"])\n  following: User @connection(fields: [\"followingId\"])\n  createdAt: String!\n}\n```\n\n4. Add Storage (S3)\n\n```sh\namplify add storage\n\n? Please select from one of the below mentioned services (Use arrow keys): Content (Images, audio, video, etc.)\n? Please provide a friendly name for your resource that will be used to label this category in the project: imagestorage\n? Please provide bucket name: \u003cUNIQUE_BUCKET_NAME\u003e\n? Who should have access: Auth and Guest users\n? What kind of access do you want for Authenticated users? create/update, read, delete\n? What kind of access do you want for Guest users? read\n```\n\n5. Deploy the resources\n\n```sh\namplify push\n```\n\n---\n\nTo learn more about uploading images in a GraphQL application with Amplify and AppSync, check out my tutorial [How to Manage Image \u0026 File Uploads \u0026 Downloads with AWS AppSync \u0026 AWS Amplify](https://dev.to/dabit3/graphql-tutorial-how-to-manage-image-file-uploads-downloads-with-aws-appsync-aws-amplify-hga)\n\n## Giphy Clone\n\nTo deploy this app, use the following steps:\n\n1. Create the Amplify project in your app\n\n```sh\namplify init\n```\n\n2. Add a lambda function\n\n```sh\namplify add function\n```\n\n3. Enter the following when prompted\n   ![lambdafunction](screenshots/giphy-clone/create-lambda-function.png)\n\n4. From the root of your project, change into your function's source directory\n\n```sh\ncd amplify/backend/function/giphyfunction/src\n```\n\n5. Install [axios](https://www.npmjs.com/package/axios) and [dotenv](https://www.npmjs.com/package/dotenv)\n\n```sh\nnpm install axios \u0026\u0026 npm install -D dotenv\n```\n\n6. Update the contents of your functions `index.js` file\n\n```js\nconst axios = require(\"axios\");\nconst dotenv = require(\"dotenv\");\ndotenv.config();\n\nexports.handler = (event, _, callback) =\u003e {\n  const { GIPHY_API_KEY } = process.env;\n  let apiUrl = `https://api.giphy.com/v1/gifs/search?api_key=${GIPHY_API_KEY}\u0026q=hello`;\n\n  if (event.arguments) {\n    const { searchTerm = \"hi\", limit = 25 } = event.arguments;\n    apiUrl = `https://api.giphy.com/v1/gifs/search?api_key=${GIPHY_API_KEY}\u0026q=${searchTerm}\u0026limit=${limit}`;\n  }\n\n  axios\n    .get(apiUrl)\n    .then(response =\u003e callback(null, response.data.data))\n    .catch(err =\u003e callback(err));\n};\n```\n\n7. Login to [Giphy's Developer portal](https://developers.giphy.com/dashboard/) and create an app to get an API Key.\n\n8. Back in the function's `src` directory, create a `.env` file and add in the API Key that was obtained in the previous step as a secret.\n\n```sh\nGIPHY_API_KEY=\u003cYOUR_API_KEY\u003e\n```\n\n**Your .env file should NOT be committed to Github**\n\n9. Head back to the root of your project\n\n```sh\ncd ../../../../../\n```\n\n10. Add the GraphQL API\n\n```sh\namplify add api\n```\n\nUse the following GraphQL Schema:\n\n```graphql\ntype Gif {\n  id: ID!\n  slug: String!\n  images: GifImage!\n}\n\ntype GifImage {\n  original: GifAttributes!\n  fixed_width: GifAttributes!\n}\n\ntype GifAttributes {\n  url: String!\n  width: String!\n  height: String!\n}\n\ntype Query {\n  getGifs(searchTerm: String, limit: Int): [Gif]\n    @function(name: \"giphyfunction-${env}\")\n}\n```\n\n11. Deploy the Resources\n\n```sh\namplify push\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdabit3%2Fgraphql-recipes","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdabit3%2Fgraphql-recipes","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdabit3%2Fgraphql-recipes/lists"}