Ở phần trước chúng ta đã nắm được cách để cài đặt AWS và sử dụng tính năng xác thực người dùng có sẵn của AWS, trong phần này chúng ta sẽ tìm hiểu thêm một vài cơ chế khá thú vị của AWS.
Analytic
Các sự kiện Analytic có thể được theo dõi bằng cách sử dụng lớp Analytics
1 2 | Analytics<span class="token punctuation">.</span><span class="token function">record</span><span class="token punctuation">(</span><span class="token string">'sale price section viewed'</span><span class="token punctuation">)</span> |
Chúng ta có thể gọi sự kiện này với nhiều thuộc tính chi tiết hơn nữa:
1 2 | Analytics<span class="token punctuation">.</span><span class="token function">record</span><span class="token punctuation">(</span><span class="token string">'sale price item viewed'</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> itemName<span class="token punctuation">:</span> <span class="token string">'USA Socks'</span> <span class="token punctuation">,</span> timestamp<span class="token punctuation">:</span> <span class="token string">'June 13 2018 4:03pm ET'</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> |
Để xem dữ liệu analytic, chúng ta có thể vào trong AWS Mobile Hub project trong console, thực hiện bằng cách ấn vào Resources ở góc trên bên phải và chọn vào Pinpoint và ấn vào dịch vụ của bạn.
1 2 3 | awsmobile console <span class="token comment">// Ấn vào Resources, sau đó Pinpoint</span> |
Storage
Amplify có một lớp Storage cho phép tương tác với React Native làm cho việc lưu trữ và truy cập các file hình ảnh, video dễ dàng hơn, và liền mạch hơn với Amazon S3.
Chúng ta có thể mở chức năng lưu trữ trong AWS Mobile Hub từ command line :
1 2 3 | awsmobile user<span class="token operator">-</span>files enable awsmobile push |
Bây giờ chúng ta có thể dùng lớp Storage từ trong app:
1 2 | <span class="token keyword">import</span> <span class="token punctuation">{</span> Storage <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'aws-amplify'</span> |
Chúng ta lưu dữ liệu vào trong storage như sau:
1 2 3 4 | Storage<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string">'test.txt'</span><span class="token punctuation">,</span> <span class="token string">'Hello'</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span> <span class="token punctuation">(</span>result <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>result<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token keyword">catch</span><span class="token punctuation">(</span>err <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> |
Và đọc nó từ storage:
1 2 3 4 | Storage<span class="token punctuation">.</span><span class="token keyword">get</span><span class="token punctuation">(</span><span class="token string">'test.txt'</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span>result <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>result<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token keyword">catch</span><span class="token punctuation">(</span>err <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> |
Chúng ta có thể lưu các file media dễ dàng vào storage (giả sử như các bạn đã cài đặt react-native-fetch-blob).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <span class="token keyword">import</span> RNFetchBlob <span class="token keyword">from</span> <span class="token string">'react-native-fetch-blob'</span><span class="token punctuation">;</span> <span class="token function">readFile</span><span class="token punctuation">(</span>filePath<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> RNFetchBlob<span class="token punctuation">.</span>fs<span class="token punctuation">.</span><span class="token function">readFile</span><span class="token punctuation">(</span>filePath<span class="token punctuation">,</span> <span class="token string">'base64'</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span>data <span class="token operator">=></span> <span class="token keyword">new</span> <span class="token class-name">Buffer</span><span class="token punctuation">(</span>data<span class="token punctuation">,</span> <span class="token string">'base64'</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">readFile</span><span class="token punctuation">(</span>imagePath<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span>buffer <span class="token operator">=></span> <span class="token punctuation">{</span> Storage<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string">'MYKEY'</span><span class="token punctuation">,</span> buffer<span class="token punctuation">,</span> <span class="token punctuation">{</span> contentType<span class="token punctuation">:</span> <span class="token string">'image/jpeg'</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token keyword">catch</span><span class="token punctuation">(</span>e <span class="token operator">=></span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>e<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> |
Để xem S3 bucket, chúng ta chạy lệnh awsmobile console
sau đó ấn vào Resources và bên dưới Amazon S3 Buckets ấn vào userfiles.
Lambda Functions
Khi mà bạn nghe thấy cụm từ “Serverless”, bạn sẽ nghĩ ngay đến hàm Lambda. Chúng ta có thể cài một trong số đó trực tiếp và kết nối nó với một trong những resource của AWS Amplify, hoặc dùng AWS Moible CLI để cài đặt nó cho chúng ta. Hãy bắt đầu dùng CLI để tạo hàm Lambda.
Để thêm Lambda đã được configure, chạy command sau:
1 2 | awsmobile cloud<span class="token operator">-</span>api enable |
awsmobile cloud-api enable
sẽ tự động tạo một API trong API Gateway cùng với Lambda function và kết nối chúng lại.
Bây giờ chúng ta nhìn vào trong project, trong phần awsmobilejs/backend/cloud-api để xem một configuration mới. Sẽ có một folder mới được tạo ra tên là sampleLambda nắm dữ hàm Lambda mới đã được triển khai cho chúng ta.
Hàm Lambda được tạo ra cho chúng ta sửu dụng AWS Serverless Express package để kết nối express server với các endpoint đã được tuỳ chỉnh. Những endpoint này có thể cập nhật trong code local và đẩy lên server bằng cách dùng awsmobile push
.
Hãy cập nhật hàm app.get
trong thư mục items
nằm trong awsmobilejs/backend/cloud-api/sampleLambda:
1 2 3 4 5 6 7 | <span class="token comment">/// rest of file omitted</span> app<span class="token punctuation">.</span><span class="token keyword">get</span><span class="token punctuation">(</span><span class="token string">'/items'</span><span class="token punctuation">,</span> <span class="token keyword">function</span><span class="token punctuation">(</span>req<span class="token punctuation">,</span> res<span class="token punctuation">)</span> <span class="token punctuation">{</span> res<span class="token punctuation">.</span><span class="token function">json</span><span class="token punctuation">(</span><span class="token punctuation">{</span> body<span class="token punctuation">:</span> <span class="token string">"HELLO WORLD"</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> |
Sau đó hãy push API này lên project AWS Mobile Hub:
awsmobile push
Bây giờ mở AWS Mobile Hub console để lấy tên API:
awsmobile console
Bấm vào Cloud Logic và sao chếp tên API (của tôi là sampleCloudApi
).
Bây giờ chúng ta sẽ kiểm tra trong hàm Lambda. Trong App.js, tạo ra thêm một hàm componentDidMount
mới.
1 2 3 4 5 | <span class="token keyword">async</span> <span class="token function">componentDidMount</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> data <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token constant">API</span><span class="token punctuation">.</span><span class="token keyword">get</span><span class="token punctuation">(</span><span class="token string">'sampleCloudApi'</span><span class="token punctuation">,</span> <span class="token string">'/items'</span><span class="token punctuation">)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'data: '</span><span class="token punctuation">,</span> data<span class="token punctuation">)</span> <span class="token punctuation">}</span> |
Quản lý API và tầng Data
AWS Amplify đưa ra một client tên là GraphQL có thể hoạt động với bất kì GraphQL API nào. Trong trường hợp của chúng ta, hãy nhìn vào AWS AppSync đã được quản lý bằng dịch vụ GraphQL.
Với AWS AppSync
, bạn có thể có một GraphQL API tương tác với bất kỳ nguồn dữ liệu nào mà bạn muốn. Có nhiều nguồn data được xây dựng ngầm như là Amazon DynamoDB, AWS Lambda Function hoặc Amazon Elasticsearch, với một hàm Lambd, bạn có thể truy câppj bất cứ dịch vụ hoặc database nào mà muốn một cách liền mạch chỉ với một tầng API đó là GraphQL nằm trong hình dạn của AppSync API của bạn.
Chúng ta sẽ đi vào một ví dụ đó là làm một Todo app.
Để bắt đầu, hãy bấm vào https://console.aws.amazon.com/appsync sau đó ấn vào CREATE API.
Từ đây hãy đặt tên cho API này và chọn Custom Schema, sau đó ấn vào Create.
Bây giờ, API đã được tạo ra và chúng ta sẽ thêm một số thông tin như là URL và Key vào.
Ấn vào Schema trong menu bên trái như sau :
1 2 3 4 5 6 7 8 9 | type Todo <span class="token punctuation">{</span> id<span class="token punctuation">:</span> <span class="token constant">ID</span><span class="token operator">!</span> name<span class="token punctuation">:</span> String<span class="token operator">!</span> completed<span class="token punctuation">:</span> Boolean<span class="token operator">!</span> <span class="token punctuation">}</span> type Query <span class="token punctuation">{</span> <span class="token function">fetchTodos</span><span class="token punctuation">(</span>id<span class="token punctuation">:</span> <span class="token constant">ID</span><span class="token operator">!</span><span class="token punctuation">)</span><span class="token punctuation">:</span> Todo <span class="token punctuation">}</span> |
ấn vào Save và ấn vào Create Resources.
Create Resources sẽ tự động cấu hình một DynamoDB database, thêm vào GraphQL Schema cho nhiều tiến trình bao gồm query, mutation, subscription và resolver mà kết nối tiến trình GraphQL vào data source.
Tiếp theo, bấm vào Queries trong menu bên trái để test thử mutation và query để đảm bảo mọi thứ hoạt động.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | mutation add { createTodo(input: { name: "Get groceries" completed: false }) { id } } query list { listTodos { items { id name completed } } } |
Bây giờ kiểm thử API này từ phía client.
Đầu tiên, chúng ta cần cập nhật configure để định danh AppSync API.
Tạo một file tên là appsync-config.js
trong root:
1 2 3 4 5 6 7 | <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">{</span> <span class="token string">'aws_appsync_graphqlEndpoint'</span><span class="token punctuation">:</span> <span class="token string">'https://*******.appsync-api.us-east-1.amazonaws.com/graphql'</span><span class="token punctuation">,</span> <span class="token string">'aws_appsync_region'</span><span class="token punctuation">:</span> <span class="token string">'us-east-1'</span><span class="token punctuation">,</span> <span class="token string">'aws_appsync_authenticationType'</span><span class="token punctuation">:</span> <span class="token string">'API_KEY'</span><span class="token punctuation">,</span> <span class="token string">'aws_appsync_apiKey'</span><span class="token punctuation">:</span> <span class="token string">'da2-*************'</span><span class="token punctuation">,</span> <span class="token punctuation">}</span> |
Tiếp theo đó là đến lượt Amplify client. Hãy cập nhật nó để nhận diện ra configure của AppSync.
1 2 3 4 5 6 7 8 | <span class="token keyword">import</span> <span class="token punctuation">{</span> AppRegistry <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'react-native'</span><span class="token punctuation">;</span> <span class="token keyword">import</span> App <span class="token keyword">from</span> <span class="token string">'./App'</span><span class="token punctuation">;</span> <span class="token keyword">import</span> Amplify <span class="token keyword">from</span> <span class="token string">'aws-amplify'</span> <span class="token keyword">import</span> config <span class="token keyword">from</span> <span class="token string">'./aws-exports'</span> <span class="token keyword">import</span> AppSyncConfig <span class="token keyword">from</span> <span class="token string">'./appsync-config'</span> <span class="token comment">// NEW</span> Amplify<span class="token punctuation">.</span><span class="token function">configure</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token operator">...</span>config<span class="token punctuation">,</span> <span class="token operator">...</span>AppSyncConfig <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token comment">// UPDATED</span> AppRegistry<span class="token punctuation">.</span><span class="token function">registerComponent</span><span class="token punctuation">(</span><span class="token string">'ServerlessProject'</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> App<span class="token punctuation">)</span><span class="token punctuation">;</span> |
Bây giờ chúng ta có thể dễ dàng tạo và thực thi tiến trình với API như sau :
Trong App.js, hãy thêm query sau:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | <span class="token keyword">import</span> React<span class="token punctuation">,</span> <span class="token punctuation">{</span> Component <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'react'</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token punctuation">{</span> StyleSheet<span class="token punctuation">,</span> Text<span class="token punctuation">,</span> View <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'react-native'</span><span class="token punctuation">;</span> <span class="token keyword">import</span> <span class="token punctuation">{</span> withAuthenticator <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'aws-amplify-react-native'</span> <span class="token keyword">import</span> <span class="token punctuation">{</span> <span class="token constant">API</span><span class="token punctuation">,</span> graphqlOperation <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'aws-amplify'</span> <span class="token keyword">const</span> query <span class="token operator">=</span> <span class="token template-string"><span class="token string">` query list { listTodos { items { id name completed } } } `</span></span> <span class="token keyword">class</span> <span class="token class-name">App</span> <span class="token keyword">extends</span> <span class="token class-name">Component</span> <span class="token punctuation">{</span> state <span class="token operator">=</span> <span class="token punctuation">{</span> todos<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token punctuation">}</span> <span class="token keyword">async</span> <span class="token function">componentDidMount</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> todos <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token constant">API</span><span class="token punctuation">.</span><span class="token function">graphql</span><span class="token punctuation">(</span><span class="token function">graphqlOperation</span><span class="token punctuation">(</span>query<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">setState</span><span class="token punctuation">(</span><span class="token punctuation">{</span> todos<span class="token punctuation">:</span> todos<span class="token punctuation">.</span>data<span class="token punctuation">.</span>listTodos<span class="token punctuation">.</span>items <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token operator"><</span>View style<span class="token operator">=</span><span class="token punctuation">{</span>styles<span class="token punctuation">.</span>container<span class="token punctuation">}</span><span class="token operator">></span> <span class="token operator"><</span>Text style<span class="token operator">=</span><span class="token punctuation">{</span>styles<span class="token punctuation">.</span>welcome<span class="token punctuation">}</span><span class="token operator">></span> Todos <span class="token operator"><</span><span class="token operator">/</span>Text<span class="token operator">></span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">.</span>todos<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token punctuation">(</span>todo<span class="token punctuation">,</span> index<span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span> <span class="token operator"><</span>Text key<span class="token operator">=</span><span class="token punctuation">{</span>index<span class="token punctuation">}</span><span class="token operator">></span><span class="token punctuation">{</span>todo<span class="token punctuation">.</span>name<span class="token punctuation">}</span><span class="token operator"><</span><span class="token operator">/</span>Text<span class="token operator">></span> <span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token operator"><</span><span class="token operator">/</span>View<span class="token operator">></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token function">withAuthenticator</span><span class="token punctuation">(</span>App<span class="token punctuation">)</span> <span class="token keyword">const</span> styles <span class="token operator">=</span> StyleSheet<span class="token punctuation">.</span><span class="token function">create</span><span class="token punctuation">(</span><span class="token punctuation">{</span> container<span class="token punctuation">:</span> <span class="token punctuation">{</span> flex<span class="token punctuation">:</span> <span class="token number">1</span><span class="token punctuation">,</span> justifyContent<span class="token punctuation">:</span> <span class="token string">'center'</span><span class="token punctuation">,</span> alignItems<span class="token punctuation">:</span> <span class="token string">'center'</span><span class="token punctuation">,</span> backgroundColor<span class="token punctuation">:</span> <span class="token string">'#F5FCFF'</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> welcome<span class="token punctuation">:</span> <span class="token punctuation">{</span> fontSize<span class="token punctuation">:</span> <span class="token number">20</span><span class="token punctuation">,</span> textAlign<span class="token punctuation">:</span> <span class="token string">'center'</span><span class="token punctuation">,</span> margin<span class="token punctuation">:</span> <span class="token number">10</span><span class="token punctuation">,</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> |
Push Notification
Việc cài đặt Push Notification kiếm nhiều thời gian hơn bất cứ loại dịch vụ nào khác vì nó cần phải có những dịch vụ từ Apple và Google. Việc cài đặt cụ thể các bạn có thể xem ở đây: iOS,Android .
Trong project của chúng ta chỉ cần như sau :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <span class="token keyword">import</span> <span class="token punctuation">{</span> PushNotification <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'aws-amplify-react-native'</span><span class="token punctuation">;</span> <span class="token comment">// get the registration token</span> PushNotification<span class="token punctuation">.</span><span class="token function">onRegister</span><span class="token punctuation">(</span><span class="token punctuation">(</span>token<span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'in app registration'</span><span class="token punctuation">,</span> token<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> PushNotification<span class="token punctuation">.</span><span class="token function">onNotification</span><span class="token punctuation">(</span><span class="token punctuation">(</span>notification<span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token comment">// Note that the notification object structure is different from Android and IOS</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'in app notification'</span><span class="token punctuation">,</span> notification<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// required on iOS only (see fetchCompletionHandler docs: https://facebook.github.io/react-native/docs/pushnotificationios.html)</span> notification<span class="token punctuation">.</span><span class="token function">finish</span><span class="token punctuation">(</span>PushNotificationIOS<span class="token punctuation">.</span>FetchResult<span class="token punctuation">.</span>NoData<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> |
Cảm ơn các bạn đã đón đọc, chúc các bạn thành công.