{"id":48018,"date":"2023-12-17T21:44:04","date_gmt":"2023-09-11T19:28:33","guid":{"rendered":"https:\/\/www.silicloud.com\/zh\/blog\/%e5%b0%9d%e8%af%95%e4%bd%bf%e7%94%a8amplify-cli-graphql-transform%e5%91%bd%e4%bb%a4%e5%92%8c%e6%8c%87%e4%bb%a4%e6%9d%a5%e6%93%8d%e4%bd%9cappsyncdynamodb%ef%bc%81model-auth-key\/"},"modified":"2024-05-04T14:05:04","modified_gmt":"2024-05-04T06:05:04","slug":"%e5%b0%9d%e8%af%95%e4%bd%bf%e7%94%a8amplify-cli-graphql-transform%e5%91%bd%e4%bb%a4%e5%92%8c%e6%8c%87%e4%bb%a4%e6%9d%a5%e6%93%8d%e4%bd%9cappsyncdynamodb%ef%bc%81model-auth-key","status":"publish","type":"post","link":"https:\/\/www.silicloud.com\/zh\/blog\/%e5%b0%9d%e8%af%95%e4%bd%bf%e7%94%a8amplify-cli-graphql-transform%e5%91%bd%e4%bb%a4%e5%92%8c%e6%8c%87%e4%bb%a4%e6%9d%a5%e6%93%8d%e4%bd%9cappsyncdynamodb%ef%bc%81model-auth-key\/","title":{"rendered":"\u5c1d\u8bd5\u4f7f\u7528Amplify CLI GraphQL Transform\u547d\u4ee4\u548c\u6307\u4ee4\u6765\u64cd\u4f5cAppSync+DynamoDB\uff01(@model @auth, @key)"},"content":{"rendered":"<h1>\u7b80\u800c\u8a00\u4e4b<\/h1>\n<p>AWS Amplify Advent Calendar 2019\u3001\u7b2c7\u7bc0\u5c06\u4ecb\u7ecd\u5982\u4f55\u4f7f\u7528AWS Amplify CLI\u5728schema.graphql\u4e2d\u8bbe\u7f6eAWS AppSync + Amazon DynamoDB\uff0c\u5e76\u4e14\u4e86\u89e3\u53ef\u7528\u7684\u4e09\u4e2a\u6307\u4ee4\uff08@model\u3001@auth\u3001@key\uff09\u3002<\/p>\n<h2>\u5e0c\u671b\u627e\u5230\u8bfb\u8005<\/h2>\n<p>\u653e\u5927\u6dfb\u52a0 API\uff0c\u5bf9\u4e8e\u90a3\u4e9b\u6709\u70b9\u4f7f\u7528\u7ecf\u9a8c\u4f46\u662f\u5bf9 @model\u3001@auth \u548c @key \u7b49\u65b9\u9762\u4e0d\u592a\u6e05\u695a\u7684\u4eba\u6765\u8bf4\uff0c\u8fd9\u7bc7\u6587\u7ae0\u5c31\u662f\u4e3a\u4ed6\u4eec\u51c6\u5907\u7684\u3002\u9a8c\u8bc1\u5e94\u7528\u662f\u7528 React \u6765\u5b9e\u73b0\u7684\uff0c\u4f46\u662f\u5373\u4f7f\u6ca1\u6709 React \u7684\u77e5\u8bc6\u4e5f\u6ca1\u5173\u7cfb\u3002<\/p>\n<h2>\u786e\u8ba4\u73af\u5883\u4e2d\u7684\u64cd\u4f5c<\/h2>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">@aws-amplify\/cli 4.5.0<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">aws-amplify 2.2.0<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">aws-amplify-react 3.1.1<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">@aws-amplify\/api 2.1.1<\/ul>\n<h1>\u505a\u597d\u51c6\u5907<\/h1>\n<h2>React\u5e94\u7528\u7a0b\u5e8f<\/h2>\n<pre class=\"post-pre\"><code>$ npx create-react-app amplify-react\r\n$ cd amplify-react\r\n$ npm start\r\n<\/code><\/pre>\n<p>\u6d4f\u89c8\u5668\u6253\u5f00\u5e76\u663e\u793a\u719f\u6089\u7684\u8d77\u59cb\u9875\u3002<\/p>\n<div><img decoding=\"async\" class=\"post-images\" title=\"\" src=\"https:\/\/cdn.silicloud.com\/blog-img\/blog\/img\/657d8280913a08637a6b083f\/10-0.png\" alt=\"image.png\" \/><\/div>\n<h2>\u653e\u5927\u5668\u7684\u521d\u59cb\u8bbe\u7f6e<\/h2>\n<p>\u5047\u8bbe\u60a8\u5df2\u7ecf\u6267\u884c\u4e86amplify configure\u3002(\u5982\u679c\u60a8\u5c1a\u672a\u6267\u884camplify configure\uff0c\u8bf7\u70b9\u51fb\u8fd9\u91cc)<br \/>\n\u8bf7\u5728${profile name}\u4e2d\u8f93\u5165\u60a8\u6b63\u5728\u4f7f\u7528\u7684 Amplify \u7684\u914d\u7f6e\u6587\u4ef6\u540d\u3002<\/p>\n<pre class=\"post-pre\"><code>amplify init\r\n? Enter a name for the project amplify-react\r\n? Enter a name for the environment dev\r\n? Choose your default editor: Vim (via Terminal, Mac OS only)\r\n? Choose the type of app that you're building javascript\r\nPlease tell us about your project\r\n? What javascript framework are you using react\r\n? Source Directory Path:  src\r\n? Distribution Directory Path: build\r\n? Build Command:  npm run-script build\r\n? Start Command: npm run-script start\r\nUsing default provider  awscloudformation\r\n\r\nFor more information on AWS Profiles, see:\r\nhttps:\/\/docs.aws.amazon.com\/cli\/latest\/userguide\/cli-multiple-profiles.html\r\n\r\n? Do you want to use an AWS profile? Yes\r\n? Please choose the profile you want to use ${profile name}\r\n<\/code><\/pre>\n<p>Amplify\u7684\u5b89\u88c5\u5df2\u7ecf\u5b8c\u6210\uff01<\/p>\n<h2>\u521b\u5efaGraphQL API<\/h2>\n<p>\u5728Amplify\u4e2d\uff0c\u53ef\u4ee5\u9009\u62e9REST API\u548cGraphQL\u4f5c\u4e3aAPI\u3002\u9009\u62e9REST API\u5c06\u521b\u5efa\u4e00\u4e2a\u7531API Gateway + Lambda\u6784\u6210\u7684REST API\u6a21\u677f\uff0c\u9009\u62e9GraphQL\u5c06\u521b\u5efa\u4e00\u4e2a\u7531AppSync + DynamoDB\u6784\u6210\u7684GraphQL\u6a21\u677f\u3002\u7531\u4e8e\u8fd9\u6b21\u60f3\u8981\u8c03\u6574GraphQL\uff0c\u6240\u4ee5\u5728Service\u4e2d\u9009\u62e9GraphQL\u3002<\/p>\n<pre class=\"post-pre\"><code>$ amplify add api\r\n? Please select from one of the below mentioned services: GraphQL\r\n? Provide API name: amplifyreact\r\n? Choose the default authorization type for the API Amazon Cognito User Pool\r\nUsing service: Cognito, provided by: awscloudformation\r\n\r\n The current configured provider is Amazon Cognito.\r\n\r\n Do you want to use the default authentication and security configuration? Default configuration\r\n Warning: you will not be able to edit these selections.\r\n How do you want users to be able to sign in? Username\r\n Do you want to configure advanced settings? No, I am done.\r\nSuccessfully added auth resource\r\n? Do you want to configure advanced settings for the GraphQL API No, I am done.\r\n? Do you have an annotated GraphQL schema? No\r\n? Do you want a guided schema creation? No\r\n? Provide a custom type name MyType \r\n<\/code><\/pre>\n<p>\u5982\u679c\u9009\u62e9\u4e86Amazon Cognito\u7528\u6237\u6c60\u4f5c\u4e3a\u9ed8\u8ba4\u7684\u6388\u6743\u7c7b\u578b\uff0c\u90a3\u4e48\u5c06\u540c\u65f6\u521b\u5efaAuth\u7c7b\u522b\u7684\u8d44\u6e90\u3002\u53ef\u4ee5\u901a\u8fc7amplify status\u6765\u786e\u8ba4\u3002<\/p>\n<pre class=\"post-pre\"><code>$ amplify status\r\nCurrent Environment: dev\r\n| Category | Resource name        | Operation | Provider plugin   |\r\n| -------- | -------------------- | --------- | ----------------- |\r\n| Auth     | amplifyreactbc0d7af4 | Create    | awscloudformation |\r\n| Api      | amplifyreact         | Create    | awscloudformation |\r\n<\/code><\/pre>\n<p>\u6211\u5df2\u786e\u8ba4Auth\u548cApi\u5df2\u7ecf\u5206\u522b\u521b\u5efa\u5b8c\u6210\u3002<\/p>\n<h1>@\u6a21\u578b<\/h1>\n<h2>@model\u662f\u4ec0\u4e48\uff1f<\/h2>\n<p>\u6839\u636e\u516c\u5f0f\u6587\u6863\uff0c\u901a\u8fc7\u4f7f\u7528@model\uff0c\u53ef\u4ee5\u8bbe\u7f6e\u4ee5\u4e0bAWS\u8d44\u6e90\u3002<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">\u30c7\u30d5\u30a9\u30eb\u30c8\u3067PAY_PER_REQUEST\u8acb\u6c42\u30e2\u30fc\u30c9\u306eAmazon DynamoDB<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">schema.graphql\u3067\u8a2d\u5b9a\u3057\u305f\u901a\u308a\u306b\u30a2\u30af\u30bb\u30b9\u53ef\u80fd\u306aAWS AppSync DataSource<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">AWS AppSync\u304cAmazon DynamoDB\u3092\u547c\u3073\u51fa\u3059\u306e\u306b\u5fc5\u8981\u306aIAM Role<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">\u6700\u59278\u3064\u306eresolver(create, update, delete, get, list, onCreate, onUpdate, onDelete)<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">mutation(create, update, delete)\u306b\u4f7f\u7528\u3059\u308bInput objects<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">list\u7cfb\u306equeriy\u3068@connection\u3067\u4f7f\u7528\u53ef\u80fd\u306a\u3001Filter input objects<\/ul>\n<p>\u5728 schema.graphql \u4e2d\uff0c\u53ea\u9700\u975e\u5e38\u5c11\u7684\u63cf\u8ff0\uff0c\u5c31\u53ef\u4ee5\u5b8c\u6210\u5982\u6b64\u591a\u7684\u8d44\u6e90\u8bbe\u7f6e\uff0c\u8fd9\u662f Amplify \u7684\u4e00\u4e2a\u5438\u5f15\u529b\u4e4b\u5904\u3002<\/p>\n<h2>\u521b\u5efaToDo\u7c7b\u578b<\/h2>\n<p>\u6253\u5f00amplify\/backend\/api\/amplifyreact\/schema.graphql\uff0c\u5176\u5185\u5bb9\u5982\u4e0b\u3002\u8fd9\u6b21\u6211\u4eec\u5c06\u5168\u90e8\u5220\u9664\u3002<\/p>\n<pre class=\"post-pre\"><code>type MyType @model {\r\n    id: ID!\r\n    title: String!\r\n    content: String!\r\n    price: Int\r\n    rating: Float\r\n}\r\n<\/code><\/pre>\n<p>\u7136\u540e\u5b9a\u4e49\u4ee5\u4e0b\u7c7b\u4f3c\u7684Todo\u6a21\u578b\u3002<\/p>\n<pre class=\"post-pre\"><code>type Todo \r\n    @model\r\n{\r\n    id: ID! \r\n    name: String!\r\n    description: String!\r\n    updatedAt: AWSDateTime \r\n    createdAt: AWSDateTime \r\n}\r\n<\/code><\/pre>\n<p>\u5728\u8fd9\u91cc\u5148\u6267\u884c`amplify push`\uff0c\u4ee5\u4f7f\u66f4\u6539\u751f\u6548\u3002<br \/>\n\u4f1a\u5f39\u51fa\u8bb8\u591a\u95ee\u9898\uff0c\u4f46\u662f\u5168\u90e8\u90fd\u53ea\u9700\u6309\u4e0bEnter\u952e\uff0c\u4e0d\u8f93\u5165\u4efb\u4f55\u5185\u5bb9\uff0c\u7136\u540e\u6309\u7167\u9ed8\u8ba4\u9009\u9879\u7ee7\u7eed\u64cd\u4f5c\u3002<\/p>\n<pre class=\"post-pre\"><code>$ amplify push\r\n\u2714 Successfully pulled backend environment dev from the cloud.\r\n\r\nCurrent Environment: dev\r\n\r\n| Category | Resource name        | Operation | Provider plugin   |\r\n| -------- | -------------------- | --------- | ----------------- |\r\n| Auth     | amplifyreactbc0d7af4 | Create    | awscloudformation |\r\n| Api      | amplifyreact         | Create    | awscloudformation |\r\n? Are you sure you want to continue? Yes\r\n\r\nThe following types do not have '@auth' enabled. Consider using @auth with @model\r\n     - Todo\r\nLearn more about @auth here: https:\/\/aws-amplify.github.io\/docs\/cli-toolchain\/graphql#auth\r\n\r\n\r\nGraphQL schema compiled successfully.\r\n\r\nEdit your schema at \/Users\/daisnaga\/Dev\/tmp\/amplify-react\/amplify\/backend\/api\/amplifyreact\/schema.graphql or place .graphql files in a directory at \/Users\/daisnaga\/Dev\/tmp\/amplify-react\/amplify\/backend\/api\/amplifyreact\/schema\r\n? Do you want to generate code for your newly created GraphQL API Yes\r\n? Choose the code generation language target javascript\r\n? Enter the file name pattern of graphql queries, mutations and subscriptions src\/graphql\/**\/*.js\r\n? Do you want to generate\/update all possible GraphQL operations - queries, mutations and subscriptions Yes\r\n? Enter maximum statement depth [increase from default if your schema is deeply nested] 2\r\n\r\n----\r\na lot of logs...\r\n----\r\n\r\nUPDATE_COMPLETE amplify-amplify-react-dev-XXXXXX AWS::CloudFormation::Stack Fri Dec 06 2019 21:36:26 GMT+0900 (Japan Standard Time)\r\n\u2714 Generated GraphQL operations successfully and saved at src\/graphql\r\n\u2714 All resources are updated in the cloud\r\n\r\nGraphQL endpoint: https:\/\/XXXXXXXX.appsync-api.us-west-2.amazonaws.com\/graphql\r\n<\/code><\/pre>\n<div><img decoding=\"async\" class=\"post-images\" title=\"\" src=\"https:\/\/cdn.silicloud.com\/blog-img\/blog\/img\/657d8280913a08637a6b083f\/33-1.png\" alt=\"image.png\" \/><\/div>\n<div><img decoding=\"async\" class=\"post-images\" title=\"\" src=\"https:\/\/cdn.silicloud.com\/blog-img\/blog\/img\/657d8280913a08637a6b083f\/34-0.png\" alt=\"image.png\" \/><\/div>\n<h2>\u521b\u5efa\u4e00\u4e2a\u7528\u4e8e\u9a8c\u8bc1\u7684Web\u5e94\u7528\u7a0b\u5e8f\u3002<\/h2>\n<p>\u7531\u4e8e\u670d\u52a1\u5668\u7aef\u5df2\u7ecf\u51c6\u5907\u5c31\u7eea\uff0c\u8ba9\u6211\u4eec\u521b\u5efa\u4e00\u4e2a\u53ef\u4ee5\u6dfb\u52a0\u548c\u786e\u8ba4Todo\u7684\u754c\u9762\u3002<\/p>\n<pre class=\"post-pre\"><code>$ npm install --save aws-amplify @aws-amplify\/api @aws-amplify\/pubsub aws-amplify-react\r\n$ vim src\/App.js\r\n<\/code><\/pre>\n<p>\u6253\u5f00\u4e00\u4e2a\u5408\u9002\u7684\u7f16\u8f91\u5668\uff0c\u7136\u540e\u6253\u5f00src\/App.js\u6587\u4ef6\uff0c\u5c06\u5176\u5185\u5bb9\u5168\u90e8\u5220\u9664\u5e76\u590d\u5236\u7c98\u8d34\u4ee5\u4e0b\u4ee3\u7801\u3002<\/p>\n<pre class=\"post-pre\"><code>import React, {useState, useEffect, useReducer } from 'react';\r\n\r\nimport Amplify, { Auth } from 'aws-amplify';\r\nimport API, { graphqlOperation } from '@aws-amplify\/api';\r\n\r\nimport { withAuthenticator } from 'aws-amplify-react'\r\n\r\nimport { createTodo } from '.\/graphql\/mutations';\r\nimport { listTodos } from '.\/graphql\/queries';\r\nimport { onCreateTodo } from '.\/graphql\/subscriptions';\r\n\r\nimport awsconfig from '.\/aws-exports';\r\nimport '.\/App.css';\r\n\r\nAmplify.configure(awsconfig);\r\n\r\nconst QUERY = 'QUERY';\r\nconst SUBSCRIPTION = 'SUBSCRIPTION';\r\n\r\nconst initialState = {\r\n  todos: [],\r\n};\r\n\r\nconst reducer = (state, action) =&gt; {\r\n  switch (action.type) {\r\n    case QUERY:\r\n      return {...state, todos: action.todos};\r\n    case SUBSCRIPTION:\r\n      return {...state, todos:[...state.todos, action.todo]}\r\n    default:\r\n      return state;\r\n  }\r\n};\r\n\r\nasync function createNewTodo() {\r\n  const todo = { name:  \"Todo \" + Math.floor(Math.random() * 10) };\r\n  await API.graphql(graphqlOperation(createTodo, { input: todo }));\r\n}\r\n\r\nfunction signOut(){\r\n  Auth.signOut()\r\n  .then(data =&gt; console.log(data))\r\n  .catch(err =&gt; console.log(err));\r\n}\r\n\r\nfunction App() {\r\n  const [state, dispatch] = useReducer(reducer, initialState);\r\n  const [user, setUser] = useState(null);\r\n\r\n  useEffect(() =&gt; {\r\n\r\n    async function getUser(){\r\n      const user = await Auth.currentUserInfo();\r\n      setUser(user);\r\n      return user\r\n    }\r\n\r\n    getUser();\r\n\r\n    async function getData() {\r\n      const todoData = await API.graphql(graphqlOperation(listTodos));\r\n      dispatch({ type: QUERY, todos: todoData.data.listTodos.items });\r\n    }\r\n\r\n    getData();\r\n\r\n\r\n    const subscription = API.graphql(graphqlOperation(onCreateTodo)).subscribe({\r\n      next: (eventData) =&gt; {\r\n        const todo = eventData.value.data.onCreateTodo;\r\n        dispatch({ type: SUBSCRIPTION, todo });\r\n      }\r\n    });\r\n\r\n    return () =&gt; subscription.unsubscribe();\r\n  }, []);\r\n\r\n  return (\r\n    &lt;div className=\"App\"&gt;\r\n      &lt;p&gt;user: {user!= null &amp;&amp; user.username}&lt;\/p&gt;\r\n      &lt;button onClick={signOut}&gt;Sign out&lt;\/button&gt;\r\n      &lt;button onClick={createNewTodo}&gt;Add Todo&lt;\/button&gt;\r\n      &lt;div&gt;\r\n        {state.todos.length &gt; 0 ? \r\n          state.todos.map((todo) =&gt; &lt;p key={todo.id}&gt;{todo.name} ({todo.createdAt})&lt;\/p&gt;) :\r\n          &lt;p&gt;Add some todos!&lt;\/p&gt; \r\n        }\r\n      &lt;\/div&gt;\r\n    &lt;\/div&gt;\r\n  );\r\n}\r\n\r\nexport default withAuthenticator(App, {\r\n  signUpConfig: {\r\n    hiddenDefaults: ['phone_number']\r\n  }\r\n});\r\n<\/code><\/pre>\n<p>\u6211\u4eec\u5df2\u7ecf\u51c6\u5907\u597d\u4e86\uff01\u8ba9\u6211\u4eec\u770b\u770b@auth\u548c@key\u3002<\/p>\n<h1>\u4ec5\u9700\u4e00\u79cd\u9009\u9879\uff0c\u8bf7\u5c06\u4ee5\u4e0b\u5185\u5bb9\u7528\u4e2d\u6587\u8fdb\u884c\u672c\u5730\u5316\u8868\u8fbe\uff1a<br \/>\n@auth<\/h1>\n<p>\u5728\u672c\u90e8\u5206\u4e2d\uff0c\u6211\u4eec\u5c06\u4f7f\u7528@auth\u6765\u786e\u4fdd\u53ea\u6709\u7528\u6237\u81ea\u5df1\u521b\u5efa\u7684\u5f85\u529e\u4e8b\u9879\u624d\u4f1a\u663e\u793a\u5728\u5217\u8868\u4e2d\u3002<\/p>\n<h2>@auth \u662f\u4ec0\u4e48\uff1f<\/h2>\n<blockquote><p>\u5e94\u7528\u7a0b\u5e8f\u9700\u8981\u6388\u6743\u624d\u80fd\u4e0e\u60a8\u7684GraphQL API\u8fdb\u884c\u4ea4\u4e92\u3002 API\u5bc6\u94a5\u6700\u9002\u7528\u4e8e\u516c\u5171API\uff08\u6216\u60a8\u5e0c\u671b\u516c\u5f00\u90e8\u5206\u7ed3\u6784\uff09\u6216\u539f\u578b\uff0c\u4e14\u5728\u90e8\u7f72\u524d\u5fc5\u987b\u6307\u5b9a\u8fc7\u671f\u65f6\u95f4\u3002IAM\u6388\u6743\u4f7f\u7528\u7b7e\u540d\u7248\u672c4\u9644\u52a0\u5230\u89d2\u8272\u7684\u7b56\u7565\u6765\u53d1\u51fa\u8bf7\u6c42\u3002\u7531Amazon Cognito\u7528\u6237\u6c60\u6216\u7b2c\u4e09\u65b9OpenID Connect\u63d0\u4f9b\u5546\u63d0\u4f9b\u7684OIDC\u4ee4\u724c\u4e5f\u53ef\u7528\u4e8e\u6388\u6743\uff0c\u542f\u7528\u6b64\u529f\u80fd\u53ea\u9700\u63d0\u4f9b\u7b80\u5355\u7684\u8bbf\u95ee\u63a7\u5236\uff0c\u8981\u6c42\u7528\u6237\u8fdb\u884c\u8eab\u4efd\u9a8c\u8bc1\u4ee5\u83b7\u5f97\u5bf9API\u64cd\u4f5c\u7684\u6700\u9ad8\u7ea7\u8bbf\u95ee\u6743\u9650\u3002\u60a8\u53ef\u4ee5\u5728\u6a21\u5f0f\u4e2d\u4f7f\u7528@auth\u6765\u8bbe\u7f6e\u66f4\u7cbe\u7ec6\u7684\u8bbf\u95ee\u63a7\u5236\uff0c\u8fd9\u6837\u53ef\u4ee5\u5229\u7528\u8fd9\u4e9b\u4ee4\u724c\u63d0\u4f9b\u7684\u6388\u6743\u5143\u6570\u636e\u6216\u8bbe\u7f6e\u5728\u6570\u636e\u5e93\u9879\u76ee\u4e0a\u7684\u6388\u6743\u5143\u6570\u636e\u3002<\/p>\n<p>@auth\u5bf9\u8c61\u7c7b\u578b\u901a\u8fc7\u4e00\u7ec4\u6388\u6743\u89c4\u5219\u8fdb\u884c\u4fdd\u62a4\uff0c\u8fd9\u4e9b\u89c4\u5219\u6bd4API\u7684\u9876\u7ea7\u6388\u6743\u63d0\u4f9b\u66f4\u591a\u63a7\u5236\u3002\u60a8\u53ef\u4ee5\u5728\u9879\u76ee\u7684\u6a21\u5f0f\u4e2d\u5bf9\u5bf9\u8c61\u7c7b\u578b\u5b9a\u4e49\u548c\u5b57\u6bb5\u5b9a\u4e49\u4f7f\u7528@auth\u6307\u4ee4\u3002<\/p>\n<p>\u5f53\u5728\u540c\u65f6\u4f7f\u7528@model\u6ce8\u89e3\u7684\u5bf9\u8c61\u7c7b\u578b\u5b9a\u4e49\u4e0a\u4f7f\u7528@auth\u6307\u4ee4\u65f6\uff0c\u8fd4\u56de\u8be5\u7c7b\u578b\u5bf9\u8c61\u7684\u6240\u6709\u89e3\u6790\u5668\u90fd\u5c06\u53d7\u5230\u4fdd\u62a4\u3002\u5f53\u5728\u5b57\u6bb5\u5b9a\u4e49\u4e0a\u4f7f\u7528@auth\u6307\u4ee4\u65f6\uff0c\u5c06\u5728\u5b57\u6bb5\u4e0a\u6dfb\u52a0\u4e00\u4e2a\u89e3\u6790\u5668\uff0c\u8be5\u89e3\u6790\u5668\u6839\u636e\u7236\u7c7b\u578b\u4e2d\u7684\u5c5e\u6027\u6765\u6388\u6743\u8bbf\u95ee\u3002<\/p>\n<p>\u6765\u6e90\uff1ahttps:\/\/aws-amplify.github.io\/docs\/cli-toolchain\/graphql#auth<\/p><\/blockquote>\n<p>\u7b80\u800c\u8a00\u4e4b\uff0c<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">Amazon Cognito User Pool\u3084\u30b5\u30fc\u30c9\u30d1\u30fc\u30c6\u30a3\u306eOIDC\u30d7\u30ed\u30d0\u30a4\u30c0\u306b\u3088\u3063\u3066\u8a8d\u8a3c(Authentication)\u3055\u308c\u305f\u30e6\u30fc\u30b6\u30fc\u306b\u5bfe\u3057\u3001\u30e6\u30fc\u30b6\u30fc\u306e\u8a8d\u8a3c\u30e1\u30bf\u30c7\u30fc\u30bf\u3092\u4f7f\u7528\u3057\u3066GraphQL API\u306e\u30a2\u30af\u30b7\u30e7\u30f3\u306b\u5bfe\u3059\u308b\u8a8d\u53ef(Authorization)\u306e\u30eb\u30fc\u30eb\u3092\u8a2d\u5b9a\u3059\u308b\u3053\u3068\u304c\u53ef\u80fd\u3067\u3059\u3002<\/ul>\n<\/li>\n<\/ul>\n<p>@auth\u3092\u4f7f\u7528\u3059\u308b\u3053\u3068\u3067API\u306e\u8a8d\u53ef\u3092\u30c8\u30c3\u30d7\u30ec\u30d9\u30eb\u3067\u884c\u3046\u3053\u3068\u304c\u53ef\u80fd\u3067\u3059<\/p>\n<p>@auth\u3068@model\u304c\u3064\u3044\u305ftype\u306eObject\u3092return\u3059\u308b\u5168\u3066\u306eGraphQL resolver\u306f\u3001\u8a2d\u5b9a\u3057\u305fAuthorization Rule\u306b\u3088\u3063\u3066\u4fdd\u8b77\u3055\u308c\u307e\u3059\u3002<\/p>\n<h2>\u5c06@auth\u6dfb\u52a0\u5230\u5f85\u529e\u4e8b\u9879\u4e2d<\/h2>\n<p>\u8ba9\u6211\u4eec\u4f7f\u7528@auth\u7f16\u5199\u8ba4\u8bc1\u89c4\u5219\uff0c\u4ee5\u4ec5\u663e\u793a\u81ea\u5df1\u521b\u5efa\u7684\u9879\u76ee\u3002\u6253\u5f00amplify\/backend\/api\/amplifyreact\/schema.graphql\u5e76\u8fdb\u884c\u4ee5\u4e0b\u66f4\u6539\u3002<\/p>\n<pre class=\"post-pre\"><code>type Todo \r\n    @model \r\n    @auth(rules: [{allow: owner}])\r\n{\r\n    id: ID! \r\n    name: String!\r\n    owner: String\r\n    description: String!\r\n    updatedAt: AWSDateTime \r\n    createdAt: AWSDateTime \r\n}\r\n<\/code><\/pre>\n<p>\u4f7f\u7528amplify push\u547d\u4ee4\uff0c\u5c06\u8fd9\u4e9b\u66f4\u6539\u540c\u6b65\u5230AWS\u8d44\u6e90\u4e0a\u3002<\/p>\n<pre class=\"post-pre\"><code>$ amplify push\r\n<\/code><\/pre>\n<h2>React\u7684\u66f4\u65b0<\/h2>\n<p>\u5f53\u4f7f\u7528\u5f00\u53d1\u8005\u5de5\u5177\u67e5\u770b\u65f6\uff0c\u53ef\u4ee5\u4eceAppSync\u8fd4\u56de\u4ee5\u4e0b\u7c7b\u578b\u7684\u9519\u8bef\u3002<\/p>\n<pre class=\"post-pre\"><code>\"Connection failed: {\"errors\":[{\"message\":\"Variable 'owner' has coerced Null value for NonNull type 'String!'\"}]}\"\r\n<\/code><\/pre>\n<p>\u56e0\u4e3a\u6307\u5b9a\u4e86@auth\uff0c\u6240\u4ee5\u5728\u8ba2\u9605\u65f6\u9700\u8981\u6307\u5b9aowner\u5b57\u6bb5\u3002\u8ba9\u6211\u4eec\u6765\u90e8\u5206\u4fee\u6539\/src\/App.js\u6587\u4ef6\u3002\u8bf7\u5220\u9664[-]\u7684\u4ee3\u7801\uff0c\u5e76\u5728\u76f8\u540c\u4f4d\u7f6e\u6dfb\u52a0[+]\u3002<\/p>\n<pre class=\"post-pre\"><code>[-]\r\nconst subscription = API.graphql(graphqlOperation(onCreateTodo)).subscribe({\r\n  next: (eventData) =&gt; {\r\n    const todo = eventData.value.data.onCreateTodo;\r\n    dispatch({ type: SUBSCRIPTION, todo });\r\n  }\r\n});\r\n\r\n[+]\r\nlet subscription;\r\ngetUser().then((user) =&gt; {\r\n  subscription = API.graphql(graphqlOperation(onCreateTodo, {owner: user.username})).subscribe({\r\n    next: (eventData) =&gt; {\r\n      const todo = eventData.value.data.onCreateTodo;\r\n      dispatch({ type: SUBSCRIPTION, todo });\r\n    }\r\n  });\r\n});\r\n<\/code><\/pre>\n<h2>\u8bf7\u786e\u8ba4\u52a8\u4f5c\u662f\u5426\u6b63\u786e<\/h2>\n<p>\u5f53\u60a8\u8fd4\u56de\u5e94\u7528\u7a0b\u5e8f\u65f6\uff0c\u60a8\u4f1a\u53d1\u73b0\u5f85\u529e\u4e8b\u9879\u672a\u663e\u793a\u3002\u8fd9\u662f\u56e0\u4e3a\u5728\u60a8\u4e4b\u524d\u521b\u5efa\u7684DynamoDB\u9879\u76ee\u4e2d\u7f3a\u5c11\u6240\u6709\u8005\u5b57\u6bb5\uff0c\u5bfc\u81f4\u901a\u8fc7@auth\u88ab\u7981\u6b62\u83b7\u53d6\u3002<\/p>\n<div><img decoding=\"async\" class=\"post-images\" title=\"\" src=\"https:\/\/cdn.silicloud.com\/blog-img\/blog\/img\/657d8280913a08637a6b083f\/59-0.png\" alt=\"image.png\" \/><\/div>\n<p>\u63a5\u4e0b\u6765\uff0c\u8ba9\u6211\u4eec\u5c1d\u8bd5\u4f7f\u7528\u53e6\u4e00\u4e2a\u7528\u6237\u8fdb\u884c\u767b\u5f55\u3002\u5148\u70b9\u51fb\u201cSignOut\u201d\u6309\u94ae\u9000\u51fa\u5f53\u524d\u8d26\u53f7\uff0c\u7136\u540e\u521b\u5efa\u53e6\u4e00\u4e2a\u8d26\u53f7\u5e76\u8fdb\u884c\u767b\u5f55\u3002\u53ef\u4ee5\u5c1d\u8bd5\u4f7f\u7528\u5176\u4ed6\u6d4f\u89c8\u5668\u6216Chrome\u7684\u9690\u8eab\u6a21\u5f0f\u6765\u8fdb\u884c\u9a8c\u8bc1\uff0c\u53ef\u80fd\u4f1a\u66f4\u65b9\u4fbf\u3002<\/p>\n<div><img decoding=\"async\" class=\"post-images\" title=\"\" src=\"https:\/\/cdn.silicloud.com\/blog-img\/blog\/img\/657d8280913a08637a6b083f\/61-0.png\" alt=\"image.png\" \/><\/div>\n<p>\u6211\u4eec\u53ef\u4ee5\u770b\u5230\u4e4b\u524d\u4f7f\u7528\u7684\u5e10\u6237\u4e2d\u521b\u5efa\u7684\u6240\u6709 Todo \u672a\u88ab\u663e\u793a\u51fa\u6765\u3002\u60a8\u53ef\u4ee5\u70b9\u51fb\u201c\u6dfb\u52a0 Todo\u201d\u6309\u94ae\uff0c\u7136\u540e\u67e5\u770b DynamoDB\u3002<\/p>\n<div><img decoding=\"async\" class=\"post-images\" title=\"\" src=\"https:\/\/cdn.silicloud.com\/blog-img\/blog\/img\/657d8280913a08637a6b083f\/63-0.png\" alt=\"image.png\" \/><\/div>\n<p>\u6211\u53ef\u4ee5\u786e\u8ba4\uff0c\u5728owner\u5b57\u6bb5\u4e2d\u521b\u5efa\u4e86\u4e00\u4e2aitem\u7684User\u7684username\u5df2\u88ab\u8f93\u5165\u3002<\/p>\n<h2>\u989d\u5916\u7684\u4e1c\u897f<\/h2>\n<p>\u6839\u636e\u516c\u5f0f\u6587\u4ef6\u663e\u793a\uff0c\u5b9e\u9645\u4e0a\u521a\u624d\u7684\u5199\u6cd5\u4e0e\u4e0b\u9762\u7684\u5199\u6cd5\u5b8c\u5168\u76f8\u540c\u3002<\/p>\n<pre class=\"post-pre\"><code>type Post\r\n  @model\r\n  @auth(\r\n    rules: [\r\n      {allow: owner, ownerField: \"owner\", operations: [create, update, delete, read]},\r\n    ])\r\n{\r\n    id: ID! \r\n    name: String!\r\n    description: String!\r\n    updatedAt: AWSDateTime \r\n    createdAt: AWSDateTime \r\n\u3000\u3000 owner: String\r\n}\r\n<\/code><\/pre>\n<p>ownerField\u3092\u7701\u7565\u3059\u308b\u3068owner<\/p>\n<p>operations\u3092\u7701\u7565\u3059\u308b\u3068\u3001create, update, delete, read<\/p>\n<p>\u53ef\u4ee5\u770b\u51fa\u6bcf\u4e2a\u90fd\u6709\u81ea\u5df1\u7684\u8bbe\u7f6e\u3002<\/p>\n<p>\u8ba9\u6211\u4eec\u6765\u770b\u4e00\u4e0b\u201callow\u201d\u6307\u7684\u662f\u4ec0\u4e48\u3002\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u5b9a\u4e49\u6765\u786e\u5b9a\u3002<\/p>\n<pre class=\"post-pre\"><code># When applied to a type, augments the application with\r\n# owner and group-based authorization rules.\r\ndirective @auth(rules: [AuthRule!]!) on OBJECT, FIELD_DEFINITION\r\ninput AuthRule {\r\n  allow: AuthStrategy!\r\n  provider: AuthProvider\r\n  ownerField: String # defaults to \"owner\" when using owner auth\r\n  identityClaim: String # defaults to \"username\" when using owner auth\r\n  groupClaim: String # defaults to \"cognito:groups\" when using Group auth\r\n  groups: [String]  # Required when using Static Group auth\r\n  groupsField: String # defaults to \"groups\" when using Dynamic Group auth\r\n  operations: [ModelOperation] # Required for finer control\r\n\r\n  # The following arguments are deprecated. It is encouraged to use the 'operations' argument.\r\n  queries: [ModelQuery]\r\n  mutations: [ModelMutation]\r\n}\r\nenum AuthStrategy { owner groups private public }\r\nenum AuthProvider { apiKey iam oidc userPools }\r\nenum ModelOperation { create update delete read }\r\n\r\n# The following objects are deprecated. It is encouraged to use ModelOperations.\r\nenum ModelQuery { get list }\r\nenum ModelMutation { create update delete }\r\n<\/code><\/pre>\n<p>\u5728allow\u4e2d\uff0c\u6211\u4eec\u6307\u5b9a\u4e86AuthStrategy\uff0c\u4e5f\u5c31\u662f\u8ba4\u53ef\u7b56\u7565\u3002\u8ba4\u53ef\u7b56\u7565\u6709\u4ee5\u4e0b\u56db\u4e2a\u9009\u9879\u3002<\/p>\n<p>owner: item\u306e\u4f5c\u6210\u8005\u3092owner\u3068\u3057\u3001owner\u306b\u95a2\u3059\u308b\u8a8d\u53ef\u3092\u6307\u5b9a\u3059\u308b<\/p>\n<p>groups: item\u306e\u4f5c\u6210\u8005\u304c\u6240\u5c5e\u3059\u308bgroup\u306b\u5bfe\u3057\u3001group\u306b\u95a2\u3059\u308b\u8a8d\u53ef\u3092\u6307\u5b9a\u3059\u308b<\/p>\n<p>private: \u8a8d\u8a3c\u6e08\u307f\u30e6\u30fc\u30b6\u30fc\u5168\u4f53\u306b\u5bfe\u3057\u3066\u8a8d\u53ef\u3092\u6307\u5b9a\u3059\u308b<\/p>\n<p>public: \u8a8d\u8a3c\u3057\u3066\u3044\u306a\u3044\u30e6\u30fc\u30b6\u30fc\u5168\u4f53\u306b\u5bfe\u3057\u3066\u8a8d\u53ef\u3092\u6307\u5b9a\u3059\u308b<\/p>\n<p>\u6b64\u5916\uff0c\u5728ownerField\u91cc\u9762\uff0c\u53ef\u4ee5\u6307\u5b9a\u5728\u4f7f\u7528owner\u7684\u6388\u6743\u7b56\u7565\u65f6\u8981\u7528\u5230\u7684\u5b57\u6bb5\u3002\u7531\u4e8e@auth\u53ef\u4ee5\u9488\u5bf9\u4e00\u4e2atype\u8fdb\u884c\u591a\u6b21\u6307\u5b9a\uff0c\u6240\u4ee5\u770b\u8d77\u6765\u53ef\u4ee5\u975e\u5e38\u7075\u6d3b\u5730\u521b\u5efa\u6388\u6743\u903b\u8f91\u3002<\/p>\n<h1>@\u5173\u952e<\/h1>\n<p>\u8ba9\u6211\u4eec\u5728\u672c\u8282\u4e2d\u4f7f\u7528@key\uff0c\u6309Todo\u7684name\u8fdb\u884c\u6392\u5e8f\u5e76\u663e\u793a\u5217\u8868\u3002<\/p>\n<h2>&#8220;@key\u662f\u4ec0\u4e48\u610f\u601d\uff1f&#8221;<\/h2>\n<blockquote><p>Amazon DynamoDB\u662f\u4e00\u79cd\u952e\u503c\u548c\u6587\u6863\u6570\u636e\u5e93\uff0c\u53ef\u4ee5\u5728\u4efb\u4f55\u89c4\u6a21\u4e0b\u63d0\u4f9b\u4e00\u4f4d\u6570\u6beb\u79d2\u7ea7\u7684\u6027\u80fd\uff0c\u4f46\u662f\u4e3a\u4e86\u4f7f\u5176\u9002\u7528\u4e8e\u60a8\u7684\u8bbf\u95ee\u6a21\u5f0f\uff0c\u9700\u8981\u4e00\u4e9b\u4e8b\u5148\u7684\u601d\u8003\u3002DynamoDB\u67e5\u8be2\u64cd\u4f5c\u53ef\u4ee5\u4f7f\u7528\u6700\u591a\u4e24\u4e2a\u5c5e\u6027\u6765\u9ad8\u6548\u5730\u67e5\u8be2\u6570\u636e\u3002\u4f20\u9012\u7ed9\u67e5\u8be2\u7684\u7b2c\u4e00\u4e2a\u67e5\u8be2\u53c2\u6570\uff08\u54c8\u5e0c\u952e\uff09\u5fc5\u987b\u4f7f\u7528\u4e25\u683c\u76f8\u7b49\u6027\uff0c\u800c\u7b2c\u4e8c\u4e2a\u5c5e\u6027\uff08\u6392\u5e8f\u952e\uff09\u53ef\u4ee5\u4f7f\u7528gt\u3001ge\u3001lt\u3001le\u3001eq\u3001beginsWith\u548cbetween\u3002DynamoDB\u53ef\u4ee5\u6709\u6548\u5730\u5b9e\u73b0\u5404\u79cd\u5f3a\u5927\u7684\u8bbf\u95ee\u6a21\u5f0f\uff0c\u9002\u7528\u4e8e\u5927\u591a\u6570\u5e94\u7528\u7a0b\u5e8f\u3002<\/p><\/blockquote>\n<p>\u5728DynamoDB\u4e2d\uff0c\u6700\u91cd\u8981\u7684\u90e8\u5206\u662f\u7c97\u4f53\u7684\u5730\u65b9\u3002\u6839\u636eDynamoDB\u7684\u67e5\u8be2\u6307\u5357\uff0c\u6700\u597d\u53ea\u4f7f\u7528\u6700\u591a\u4e24\u4e2a\u5c5e\u6027\u8fdb\u884c\u67e5\u8be2\u3002\u8fd9\u4e24\u4e2a\u5c5e\u6027\u88ab\u79f0\u4e3a\u5206\u533a\u952e\uff08PK\uff09\u548c\u6392\u5e8f\u952e\uff08SK\uff09\u3002\u6839\u636eDynamoDB\u7684\u4e13\u4e1a\u8d44\u6599\uff0c\u53ef\u4ee5\u5c06PK\u5355\u72ec\u4f7f\u7528\uff0c\u6216\u8005\u5c06PK\u548cSK\u7ec4\u5408\u5728\u4e00\u8d77\u4f5c\u4e3a\u4e3b\u952e\u4f7f\u7528\u3002<\/p>\n<blockquote><p>\u5206\u533a\u8868<\/p>\n<p>\u5206\u533a\u952e\u53ef\u4f5c\u4e3a\u4e3b\u952e\u5355\u72ec\u4f7f\u7528<br \/>\n\u7528\u4e8e\u6784\u5efa\u65e0\u5e8f\u54c8\u5e0c\u7d22\u5f15\u7684\u952e<br \/>\n\u8868\u53ef\u80fd\u88ab\u5206\u5272\uff08\u5206\u533a\uff09\u4ee5\u4fdd\u8bc1\u6027\u80fd<\/p>\n<p>\u5206\u533a\u6392\u5e8f\u8868<\/p>\n<p>\u53ef\u5c06\u5206\u533a + \u6392\u5e8f\u4f5c\u4e3a\u4e3b\u952e<br \/>\n\u4e3a\u4fdd\u8bc1\u4f7f\u7528\u76f8\u540c\u7684\u5206\u533a\u952e\u65f6\u6570\u636e\u7684\u987a\u5e8f\uff0c\u4f7f\u7528\u6392\u5e8f\u952e<br \/>\n\u5206\u533a\u952e\u6570\u91cf\u6ca1\u6709\u4e0a\u9650\uff08\u4f7f\u7528\u672c\u5730\u4e8c\u7ea7\u7d22\u5f15\u65f6\u6709\u6570\u636e\u5927\u5c0f\u9650\u5236\uff09<\/p><\/blockquote>\n<p>@key\u7684\u4e3b\u8981\u4f5c\u7528\u662f\u6307\u5b9aPK\u548cSK\u3002\u5982\u679c\u4e0d\u4f7f\u7528PK\u548cSK\u6765\u7f16\u5199\u67e5\u8be2\uff0c\u5c06\u626b\u63cfDynamoDB\u8868\u4e2d\u7684\u6240\u6709\u5185\u5bb9\uff0c\u6548\u7387\u975e\u5e38\u4f4e\u4e0b\u3002\u4f4e\u6548\u4e0d\u4ec5\u5bfc\u81f4\u67e5\u8be2\u65f6\u95f4\u957f\uff0c\u8fd8\u4f1a\u589e\u52a0\u8d39\u7528\uff0c\u56e0\u4e3a\u6309\u91cf\u8ba1\u8d39\u3002(\u5728Amplify\u7684schema.graphql\u4e2d\u8bbe\u7f6e\u7684\u67e5\u8be2\u4e2d\uff0c\u9664\u4e86\u4f7f\u7528@key\u6307\u5b9a\u7684\u5b57\u6bb5\u4ee5\u5916\uff0c\u65e0\u6cd5\u5c06\u5176\u4ed6\u5b57\u6bb5\u7528\u4f5c\u8f93\u5165\u3002\u5982\u679c\u9700\u8981\u8fdb\u884c\u5168\u6587\u641c\u7d22\u7b49\u64cd\u4f5c\uff0c\u5efa\u8bae\u4f7f\u7528@searchable\u5e76\u5229\u7528ElasticSearch\u8d44\u6e90\u6765\u521b\u5efaResolver\u3002)<br \/>\n\u56e0\u6b64\uff0c\u5173\u952e\u662f\u5728\u8bbe\u8ba1\u5e94\u7528\u7a0b\u5e8f\u7684\u6574\u4f53\u67b6\u6784\u65f6\u786e\u5b9a\u4f7f\u7528\u54ea\u79cdKey\u6765\u63d0\u53d6\u6bcf\u4e2a\u9879\uff0c\u5e76\u4ece\u800c\u9006\u5411\u8bbe\u8ba1PK\u548cSK\u3002\u8fd9\u4e00\u8fc7\u7a0b\u53ef\u80fd\u770b\u8d77\u6765\u6709\u70b9\u7e41\u7410\uff0c\u4f46\u901a\u8fc7\u9002\u5f53\u7684\u8bbe\u8ba1\uff0c\u53ef\u4ee5\u7f29\u77ed\u5728\u6269\u5c55\u65f6\u8fdb\u884c\u67e5\u8be2\u65f6\u7684\u5ef6\u8fdf\u65f6\u95f4\u3002\u6709\u5173\u5177\u4f53\u7684DynamoDB\u8bbe\u8ba1\u6a21\u5f0f\uff0c\u8bf7\u53c2\u9605\u6b64\u5904\u3002<\/p>\n<p>\u5728\u4e0d\u8bbe\u7f6e@key\u7684\u60c5\u51b5\u4e0b\u521b\u5efa\u7684DynamoDB Table\u9ed8\u8ba4\u5c06\u4ec0\u4e48\u4f5c\u4e3aPK\u548cSK\uff1f<\/p>\n<div><img decoding=\"async\" class=\"post-images\" title=\"\" src=\"https:\/\/cdn.silicloud.com\/blog-img\/blog\/img\/657d8280913a08637a6b083f\/83-0.png\" alt=\"image.png\" \/><\/div>\n<p>\u5f53\u786e\u8ba4\u540e\uff0c\u6211\u4eec\u53d1\u73b0\u4f5c\u4e3a\u4e3b\u952e\uff08PK\uff09\uff0cid\u88ab\u8bbe\u7f6e\uff0c\u4f46\u662fSK\u672a\u8bbe\u5b9a\u4efb\u4f55\u503c\u3002<\/p>\n<h2>GraphQL \u8bf7\u6c42\u8fd4\u56de\u65f6\u8fdb\u884c\u6392\u5e8f\u5e76\u8fd4\u56de<\/h2>\n<p>\u7531\u65bc\u7121\u6cd5\u66f4\u6539\u4e00\u6b21\u6027\u5275\u5efa\u7684DynamoDB\u8868\u7684\u4e3b\u5206\u5272\u9375\uff08PK\uff09\u548c\u6392\u5e8f\u9375\uff08SK\uff09\uff0c\u56e0\u6b64\u9700\u8981\u91cd\u65b0\u5275\u5efa\u8a72\u8868\u3002\u9019\u6b21\u6211\u5011\u5c07\u4f7f\u7528DynamoDB\u7684\u5168\u5c40\u4e8c\u7d1a\u7d22\u5f15\uff08GSI\uff09\uff0c\u901a\u904e\u4f7f\u7528description\u5b57\u6bb5\u4f86\u5be6\u73fe\u6392\u5e8f\u529f\u80fd\u3002<\/p>\n<blockquote><p>\u4e3a\u4e86\u9002\u5e94\u8fd9\u79cd\u9700\u6c42\uff0c\u53ef\u4ee5\u901a\u8fc7\u521b\u5efa\u4e00\u4e2a\u6216\u591a\u4e2a\u5168\u5c40\u4e8c\u7ea7\u7d22\u5f15\uff0c\u5728Amazon DynamoDB\u4e0a\u5bf9\u8be5\u7d22\u5f15\u53d1\u51faQuery\u8bf7\u6c42\u6765\u4f7f\u7528\u5404\u79cd\u5c5e\u6027\u4f5c\u4e3a\u67e5\u8be2\u6761\u4ef6\u6267\u884c\u4e0d\u540c\u7c7b\u578b\u7684\u67e5\u8be2\u3002<\/p><\/blockquote>\n<p>\u6211\u4eec\u5c06\u4e0d\u8be6\u7ec6\u89e3\u91caGSI\uff0c\u7b80\u800c\u8a00\u4e4b\u5c31\u662f\u521b\u5efa\u4e86\u53e6\u4e00\u4e2a\u8868\uff0c\u6539\u53d8\u4e86PK\u548cSK\uff0c\u4ee5\u907f\u514d\u626b\u63cf\u5e76\u5feb\u901f\u6267\u884c\u7279\u5b9a\u67e5\u8be2\u7684\u529f\u80fd\u3002<\/p>\n<p>\u8fd9\u6b21\u6211\u4eec\u5c06\u521b\u5efa\u4e00\u4e2a\u65b0\u7684GSI\uff0c\u91c7\u7528owner\u4f5c\u4e3aPK\uff0cname\u4f5c\u4e3aSK\u3002<\/p>\n<pre class=\"post-pre\"><code>type Todo \r\n    @model \r\n    @auth(rules: [{allow: owner}])\r\n    @key(name: \"SortByName\", fields:[\"owner\", \"name\"], queryField: \"listTodosSortedByName\" )\r\n{\r\n    id: ID! \r\n    name: String!\r\n    owner: String\r\n    updatedAt: AWSDateTime \r\n    createdAt: AWSDateTime \r\n}\r\n<\/code><\/pre>\n<p>name\u306fGSI\u306e\u540d\u524d\u3067\u3059<\/p>\n<p>fields\u306e\u914d\u5217\u306e\u3046\u3061\u3001\u4e00\u3064\u76ee\u304cPK\u3001\u4e8c\u3064\u76ee\u304cSK\u306b\u306a\u308a\u307e\u3059<\/p>\n<p>queryField\u306f\u3001\u3053\u306eGSI\u3092\u7528\u3044\u3066query\u3059\u308b\u6642\u306b\u4f7f\u7528\u3059\u308bresolver\u306e\u540d\u524d\u3067\u3059<br \/>\n\u660e\u793a\u7684\u306bowner\u30d5\u30a3\u30fc\u30eb\u30c9\u3092\u66f8\u304b\u306a\u3044\u3068@key\u3067\u6307\u5b9a\u3067\u304d\u306a\u3044\u305f\u3081\u3001owner\u30d5\u30a3\u30fc\u30eb\u30c9\u3092\u8db3\u3057\u3066\u3044\u307e\u3059<\/p>\n<p>\u90a3\u4e48\uff0c\u8bf7\u5728App.js\u4e2d\u8fdb\u884c\u66f4\u6539\u4ee5\u4f7f\u7528\u6b64\u89e3\u6790\u5668\u3002\u8bf7\u5220\u9664[-]\u5904\u7684\u4ee3\u7801\uff0c\u5e76\u5728\u76f8\u540c\u4f4d\u7f6e\u6dfb\u52a0[+]\u3002<\/p>\n<pre class=\"post-pre\"><code>[-] \r\nimport { listTodos} from '.\/graphql\/queries';\r\n\r\n[+] \r\nimport { listTodos, listTodosSortedByName } from '.\/graphql\/queries';\r\n<\/code><\/pre>\n<pre class=\"post-pre\"><code>[-]\r\nasync function getData() {\r\n    const todoData = await API.graphql(graphqlOperation(listTods));\r\n    dispatch({ type: QUERY, todos: todoData.data.listTodos.items });\r\n}\r\ngetData();\r\n\r\n[+]\r\nasync function getData(user) {\r\n    const todoData = await API.graphql(graphqlOperation(listTodosSortedByName, {owner: user.username}));\r\n    dispatch({ type: QUERY, todos: todoData.data.listTodosSortedByName.items });\r\n}\r\ngetUser().then((user) =&gt; getData(user));\r\n\r\n<\/code><\/pre>\n<h2>\u786e\u8ba4\u884c\u52a8<\/h2>\n<p>\u5f53\u66f4\u6539\u5b8c\u6210\u540e\uff0c\u8bf7\u8fd4\u56de\u5e94\u7528\u7a0b\u5e8f\uff01\u53ef\u4ee5\u786e\u8ba4Todo\u4ee5\u521b\u5efa\u987a\u5e8f\u663e\u793a\uff0c\u73b0\u5728\u5df2\u6309Todo\u7684\u540d\u79f0\u5347\u5e8f\u8fdb\u884c\u4e86\u66f4\u6539\u3002<\/p>\n<div><img decoding=\"async\" class=\"post-images\" title=\"\" src=\"https:\/\/cdn.silicloud.com\/blog-img\/blog\/img\/657d8280913a08637a6b083f\/97-0.png\" alt=\"image.png\" \/><\/div>\n<p>\u5728\u8fd9\u4e2a\u4f8b\u5b50\u4e2d\uff0c\u9879\u76ee\u6570\u91cf\u8f83\u5c11\uff0c\u4f60\u53ef\u80fd\u89c9\u5f97\u5373\u4f7f\u4e0d\u4f7f\u7528@key\uff0c\u5728React\u7684\u4e00\u4fa7\u8fdb\u884c\u6392\u5e8f\u4e5f\u6ca1\u6709\u592a\u5927\u533a\u522b\u3002\u4f46\u5728\u5b9e\u9645\u60c5\u51b5\u4e2d\uff0c\u5982\u679c\u9879\u76ee\u6570\u91cf\u975e\u5e38\u5927\uff0c\u5904\u7406\u5728\u524d\u7aef\u53d8\u5f97\u56f0\u96be\uff0c\u6216\u8005\u5728\u4f7f\u7528NextToken\u5b9e\u73b0\u5206\u9875\u65f6\uff0c\u5b83\u4f1a\u53d1\u6325\u4f5c\u7528\u3002<\/p>\n<h1>\u603b\u7ed3<\/h1>\n<p>@model\u306fAppSync\u3068DynamoDB\u306e\u30ea\u30bd\u30fc\u30b9\u3092\u6e96\u5099\u3059\u308b\u3088\u30fc\u3068\u3044\u3046\u5ba3\u8a00\u3067\u3059\u3002<\/p>\n<p>@auth\u3092\u4f7f\u3044\u3001AppSync\u306eResolver\u306b\u5bfe\u3059\u308b\u30a2\u30af\u30bb\u30b9\u6a29\u9650\u306e\u8a2d\u5b9a\u3092\u884c\u3046\u3053\u3068\u304c\u53ef\u80fd\u3067\u3059\u3002<\/p>\n<p>@key\u3092\u4f7f\u3046\u3053\u3068\u3067\u3001\u4efb\u610f\u306e\u30d5\u30a3\u30fc\u30eb\u30c9\u3092\u4f7f\u7528\u3057\u305fQuery Resolver\u3092\u4f5c\u6210\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002<\/p>\n<p>\u975e\u5e38\u611f\u8c22\u60a8\u9605\u8bfb\u5230\u6700\u540e\uff01\u660e\u5929\u662fAWS Amplify\u5faa\u73af\u65e5\u5386\u7684@FumihikoSHIROYAMA \u6d3b\u52a8\uff01<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u7b80\u800c\u8a00\u4e4b AWS Amplify Advent Calendar 2019\u3001\u7b2c7\u7bc0\u5c06\u4ecb\u7ecd\u5982\u4f55\u4f7f\u7528AWS Amp [&hellip;]<\/p>\n","protected":false},"author":12,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-48018","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v21.5 (Yoast SEO v21.5) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>\u5c1d\u8bd5\u4f7f\u7528Amplify CLI GraphQL Transform\u547d\u4ee4\u548c\u6307\u4ee4\u6765\u64cd\u4f5cAppSync+DynamoDB\uff01(@model @auth, @key) - Blog - Silicon Cloud<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.silicloud.com\/zh\/blog\/\u5c1d\u8bd5\u4f7f\u7528amplify-cli-graphql-transform\u547d\u4ee4\u548c\u6307\u4ee4\u6765\u64cd\u4f5cappsyncdynamodb\uff01model-auth-key\/\" \/>\n<meta property=\"og:locale\" content=\"zh_CN\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"\u5c1d\u8bd5\u4f7f\u7528Amplify CLI GraphQL Transform\u547d\u4ee4\u548c\u6307\u4ee4\u6765\u64cd\u4f5cAppSync+DynamoDB\uff01(@model @auth, @key)\" \/>\n<meta property=\"og:description\" content=\"\u7b80\u800c\u8a00\u4e4b AWS Amplify Advent Calendar 2019\u3001\u7b2c7\u7bc0\u5c06\u4ecb\u7ecd\u5982\u4f55\u4f7f\u7528AWS Amp [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.silicloud.com\/zh\/blog\/\u5c1d\u8bd5\u4f7f\u7528amplify-cli-graphql-transform\u547d\u4ee4\u548c\u6307\u4ee4\u6765\u64cd\u4f5cappsyncdynamodb\uff01model-auth-key\/\" \/>\n<meta property=\"og:site_name\" content=\"Blog - Silicon Cloud\" \/>\n<meta property=\"article:published_time\" content=\"2023-09-11T19:28:33+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-05-04T06:05:04+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/cdn.silicloud.com\/blog-img\/blog\/img\/657d8280913a08637a6b083f\/10-0.png\" \/>\n<meta name=\"author\" content=\"\u9038, \u79d1\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"\u4f5c\u8005\" \/>\n\t<meta name=\"twitter:data1\" content=\"\u9038, \u79d1\" \/>\n\t<meta name=\"twitter:label2\" content=\"\u9884\u8ba1\u9605\u8bfb\u65f6\u95f4\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 \u5206\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/%e5%b0%9d%e8%af%95%e4%bd%bf%e7%94%a8amplify-cli-graphql-transform%e5%91%bd%e4%bb%a4%e5%92%8c%e6%8c%87%e4%bb%a4%e6%9d%a5%e6%93%8d%e4%bd%9cappsyncdynamodb%ef%bc%81model-auth-key\/\",\"url\":\"https:\/\/www.silicloud.com\/zh\/blog\/%e5%b0%9d%e8%af%95%e4%bd%bf%e7%94%a8amplify-cli-graphql-transform%e5%91%bd%e4%bb%a4%e5%92%8c%e6%8c%87%e4%bb%a4%e6%9d%a5%e6%93%8d%e4%bd%9cappsyncdynamodb%ef%bc%81model-auth-key\/\",\"name\":\"\u5c1d\u8bd5\u4f7f\u7528Amplify CLI GraphQL Transform\u547d\u4ee4\u548c\u6307\u4ee4\u6765\u64cd\u4f5cAppSync+DynamoDB\uff01(@model @auth, @key) - Blog - Silicon Cloud\",\"isPartOf\":{\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#website\"},\"datePublished\":\"2023-09-11T19:28:33+00:00\",\"dateModified\":\"2024-05-04T06:05:04+00:00\",\"author\":{\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/85c1dae56e6ea1e695c73d33c684d487\"},\"breadcrumb\":{\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/%e5%b0%9d%e8%af%95%e4%bd%bf%e7%94%a8amplify-cli-graphql-transform%e5%91%bd%e4%bb%a4%e5%92%8c%e6%8c%87%e4%bb%a4%e6%9d%a5%e6%93%8d%e4%bd%9cappsyncdynamodb%ef%bc%81model-auth-key\/#breadcrumb\"},\"inLanguage\":\"zh-Hans\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.silicloud.com\/zh\/blog\/%e5%b0%9d%e8%af%95%e4%bd%bf%e7%94%a8amplify-cli-graphql-transform%e5%91%bd%e4%bb%a4%e5%92%8c%e6%8c%87%e4%bb%a4%e6%9d%a5%e6%93%8d%e4%bd%9cappsyncdynamodb%ef%bc%81model-auth-key\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/%e5%b0%9d%e8%af%95%e4%bd%bf%e7%94%a8amplify-cli-graphql-transform%e5%91%bd%e4%bb%a4%e5%92%8c%e6%8c%87%e4%bb%a4%e6%9d%a5%e6%93%8d%e4%bd%9cappsyncdynamodb%ef%bc%81model-auth-key\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"\u9996\u9875\",\"item\":\"https:\/\/www.silicloud.com\/zh\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"\u5c1d\u8bd5\u4f7f\u7528Amplify CLI GraphQL Transform\u547d\u4ee4\u548c\u6307\u4ee4\u6765\u64cd\u4f5cAppSync+DynamoDB\uff01(@model @auth, @key)\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#website\",\"url\":\"https:\/\/www.silicloud.com\/zh\/blog\/\",\"name\":\"Blog - Silicon Cloud\",\"description\":\"\",\"inLanguage\":\"zh-Hans\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/85c1dae56e6ea1e695c73d33c684d487\",\"name\":\"\u9038, \u79d1\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"zh-Hans\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/c94f6d9cbbfbca863fab309840bd690c153c95f8490c290ad2ed54dd693dad16?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/c94f6d9cbbfbca863fab309840bd690c153c95f8490c290ad2ed54dd693dad16?s=96&d=mm&r=g\",\"caption\":\"\u9038, \u79d1\"},\"url\":\"https:\/\/www.silicloud.com\/zh\/blog\/author\/keyi\/\"},{\"@type\":\"ImageObject\",\"inLanguage\":\"zh-Hans\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/%e5%b0%9d%e8%af%95%e4%bd%bf%e7%94%a8amplify-cli-graphql-transform%e5%91%bd%e4%bb%a4%e5%92%8c%e6%8c%87%e4%bb%a4%e6%9d%a5%e6%93%8d%e4%bd%9cappsyncdynamodb%ef%bc%81model-auth-key\/#local-main-organization-logo\",\"url\":\"\",\"contentUrl\":\"\",\"caption\":\"Blog - Silicon Cloud\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"\u5c1d\u8bd5\u4f7f\u7528Amplify CLI GraphQL Transform\u547d\u4ee4\u548c\u6307\u4ee4\u6765\u64cd\u4f5cAppSync+DynamoDB\uff01(@model @auth, @key) - Blog - Silicon Cloud","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.silicloud.com\/zh\/blog\/\u5c1d\u8bd5\u4f7f\u7528amplify-cli-graphql-transform\u547d\u4ee4\u548c\u6307\u4ee4\u6765\u64cd\u4f5cappsyncdynamodb\uff01model-auth-key\/","og_locale":"zh_CN","og_type":"article","og_title":"\u5c1d\u8bd5\u4f7f\u7528Amplify CLI GraphQL Transform\u547d\u4ee4\u548c\u6307\u4ee4\u6765\u64cd\u4f5cAppSync+DynamoDB\uff01(@model @auth, @key)","og_description":"\u7b80\u800c\u8a00\u4e4b AWS Amplify Advent Calendar 2019\u3001\u7b2c7\u7bc0\u5c06\u4ecb\u7ecd\u5982\u4f55\u4f7f\u7528AWS Amp [&hellip;]","og_url":"https:\/\/www.silicloud.com\/zh\/blog\/\u5c1d\u8bd5\u4f7f\u7528amplify-cli-graphql-transform\u547d\u4ee4\u548c\u6307\u4ee4\u6765\u64cd\u4f5cappsyncdynamodb\uff01model-auth-key\/","og_site_name":"Blog - Silicon Cloud","article_published_time":"2023-09-11T19:28:33+00:00","article_modified_time":"2024-05-04T06:05:04+00:00","og_image":[{"url":"https:\/\/cdn.silicloud.com\/blog-img\/blog\/img\/657d8280913a08637a6b083f\/10-0.png"}],"author":"\u9038, \u79d1","twitter_card":"summary_large_image","twitter_misc":{"\u4f5c\u8005":"\u9038, \u79d1","\u9884\u8ba1\u9605\u8bfb\u65f6\u95f4":"7 \u5206"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.silicloud.com\/zh\/blog\/%e5%b0%9d%e8%af%95%e4%bd%bf%e7%94%a8amplify-cli-graphql-transform%e5%91%bd%e4%bb%a4%e5%92%8c%e6%8c%87%e4%bb%a4%e6%9d%a5%e6%93%8d%e4%bd%9cappsyncdynamodb%ef%bc%81model-auth-key\/","url":"https:\/\/www.silicloud.com\/zh\/blog\/%e5%b0%9d%e8%af%95%e4%bd%bf%e7%94%a8amplify-cli-graphql-transform%e5%91%bd%e4%bb%a4%e5%92%8c%e6%8c%87%e4%bb%a4%e6%9d%a5%e6%93%8d%e4%bd%9cappsyncdynamodb%ef%bc%81model-auth-key\/","name":"\u5c1d\u8bd5\u4f7f\u7528Amplify CLI GraphQL Transform\u547d\u4ee4\u548c\u6307\u4ee4\u6765\u64cd\u4f5cAppSync+DynamoDB\uff01(@model @auth, @key) - Blog - Silicon Cloud","isPartOf":{"@id":"https:\/\/www.silicloud.com\/zh\/blog\/#website"},"datePublished":"2023-09-11T19:28:33+00:00","dateModified":"2024-05-04T06:05:04+00:00","author":{"@id":"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/85c1dae56e6ea1e695c73d33c684d487"},"breadcrumb":{"@id":"https:\/\/www.silicloud.com\/zh\/blog\/%e5%b0%9d%e8%af%95%e4%bd%bf%e7%94%a8amplify-cli-graphql-transform%e5%91%bd%e4%bb%a4%e5%92%8c%e6%8c%87%e4%bb%a4%e6%9d%a5%e6%93%8d%e4%bd%9cappsyncdynamodb%ef%bc%81model-auth-key\/#breadcrumb"},"inLanguage":"zh-Hans","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.silicloud.com\/zh\/blog\/%e5%b0%9d%e8%af%95%e4%bd%bf%e7%94%a8amplify-cli-graphql-transform%e5%91%bd%e4%bb%a4%e5%92%8c%e6%8c%87%e4%bb%a4%e6%9d%a5%e6%93%8d%e4%bd%9cappsyncdynamodb%ef%bc%81model-auth-key\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.silicloud.com\/zh\/blog\/%e5%b0%9d%e8%af%95%e4%bd%bf%e7%94%a8amplify-cli-graphql-transform%e5%91%bd%e4%bb%a4%e5%92%8c%e6%8c%87%e4%bb%a4%e6%9d%a5%e6%93%8d%e4%bd%9cappsyncdynamodb%ef%bc%81model-auth-key\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"\u9996\u9875","item":"https:\/\/www.silicloud.com\/zh\/blog\/"},{"@type":"ListItem","position":2,"name":"\u5c1d\u8bd5\u4f7f\u7528Amplify CLI GraphQL Transform\u547d\u4ee4\u548c\u6307\u4ee4\u6765\u64cd\u4f5cAppSync+DynamoDB\uff01(@model @auth, @key)"}]},{"@type":"WebSite","@id":"https:\/\/www.silicloud.com\/zh\/blog\/#website","url":"https:\/\/www.silicloud.com\/zh\/blog\/","name":"Blog - Silicon Cloud","description":"","inLanguage":"zh-Hans"},{"@type":"Person","@id":"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/85c1dae56e6ea1e695c73d33c684d487","name":"\u9038, \u79d1","image":{"@type":"ImageObject","inLanguage":"zh-Hans","@id":"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/c94f6d9cbbfbca863fab309840bd690c153c95f8490c290ad2ed54dd693dad16?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/c94f6d9cbbfbca863fab309840bd690c153c95f8490c290ad2ed54dd693dad16?s=96&d=mm&r=g","caption":"\u9038, \u79d1"},"url":"https:\/\/www.silicloud.com\/zh\/blog\/author\/keyi\/"},{"@type":"ImageObject","inLanguage":"zh-Hans","@id":"https:\/\/www.silicloud.com\/zh\/blog\/%e5%b0%9d%e8%af%95%e4%bd%bf%e7%94%a8amplify-cli-graphql-transform%e5%91%bd%e4%bb%a4%e5%92%8c%e6%8c%87%e4%bb%a4%e6%9d%a5%e6%93%8d%e4%bd%9cappsyncdynamodb%ef%bc%81model-auth-key\/#local-main-organization-logo","url":"","contentUrl":"","caption":"Blog - Silicon Cloud"}]}},"_links":{"self":[{"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/posts\/48018","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/users\/12"}],"replies":[{"embeddable":true,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/comments?post=48018"}],"version-history":[{"count":2,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/posts\/48018\/revisions"}],"predecessor-version":[{"id":98765,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/posts\/48018\/revisions\/98765"}],"wp:attachment":[{"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/media?parent=48018"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/categories?post=48018"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/tags?post=48018"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}