Xây dựng ứng dụng thời gian thực với Amazon EventBridge và AWS AppSync

Bởi James Beswick | vào ngày 30 THG 1 2024 | trong Amazon EventBridge, AWS AppSync, Serverless

Bài viết này được viết bởi Josh Kahn, Tech Leader, Serverless.

Amazon EventBridge hiện đã hỗ trợ xuất bản sự kiện đến các API GraphQL của AWS AppSync. Sự tích hợp mới này cho phép người xây dựng dễ dàng xuất bản sự kiện đến một loạt rộng hơn các người tiêu thụ và đơn giản hóa việc cập nhật khách hàng với dữ liệu gần thời gian thực. Bạn có thể sử dụng EventBridge và AWS AppSync để xây dựng kiến trúc dựa trên sự kiện, kiến trúc subscription-based event-driven.

Để minh họa việc sử dụng EventBridge với AWS AppSync, hãy xem xét một kịch bản vận hành sân bay đơn giản. Trong ví dụ này, các hãng hàng không đăng tải các sự kiện chuyến bay (ví dụ: lên máy bay, đẩy lùi, thay đổi cổng và trễ chuyến) đến một dịch vụ duy trì trạng thái chuyến bay trên các màn hình trong sân bay. Các hãng hàng không cũng đăng tải các sự kiện này cho các đơn vị khác tại sân bay, như nhân viên xử lý hành lý và bảo trì, nhưng không dành cho hành khách. Điều này mô tả một cái nhìn tổng quát về hệ thống:

Conceptual view of the system

Hành khách muốn xem các thông tin tại sân bay được cập nhật nhanh và chính xác. Có nhiều cách để thiết kế ứng dụng hiển thị để dữ liệu luôn được cập nhật. Phổ biến, các cách này bao gồm ứng dụng truy vấn một số API hoặc ứng dụng đăng ký theo dõi thay đổi dữ liệu.

Trong tình huống sau sẽ được cải thiện vì các thay đổi dữ liệu nhỏ và tăng dần so với lượng thông tin lớn được hiển thị. Trong trường hợp trễ chuyến bay, ví dụ, màn hình cập nhật trạng thái và thời gian khởi hành nhưng không có chi tiết khác của một chuyến bay duy nhất trong một danh sách thông tin chuyến bay lớn hơn.

Flight board

AWS AppSync có thể cho phép các máy client lắng nghe các thay đổi dữ liệu ở thời gian thực thông qua việc sử dụng các đăng ký GraphQL. Các đăng ký này được triển khai bằng cách sử dụng kết nối WebSocket giữa máy client và dịch vụ AWS AppSync. Ứng dụng hiển thị của máy client gọi thực hiện thao tác đăng ký GraphQL để thiết lập một kết nối an toàn. WS AppSync sẽ tự động đẩy các thay đổi dữ liệu (hoặc biến đổi) thông qua API GraphQL đến các bên đăng ký sử dụng kết nối đó.

Trước đây, các nhà xây dựng có thể sử dụng EventBridge API Destinations để kết nối các sự kiện được tạo ra và định tuyến thông qua EventBridge đến AWS AppSync, như được mô tả trong bài đăng trên blog trước đó và có sẵn ở ​​Serverless Land patterns (API Key, OAuth). Phương pháp này hữu ích trong việc xử lý các cập nhật “out-of-band” trong đó dữ liệu thay đổi bên ngoài một đợt mutation của AWS AppSync. Các cập nhật “out-of-band” thường yêu cầu một nguồn dữ liệu NONE trong AWS AppSync để thông báo cho các bên đăng ký về các thay đổi, như mô tả trong AWS re:Post Knowledge Center. Việc thêm AWS AppSync như một mục tiêu cho EventBridge đơn giản hóa những trường hợp sử dụng này vì bạn có thể kích hoạt một biến đổi đáp ứng một sự kiện mà không cần code bổ sung.

Những sự kiện vận hành Sân bay

Mở rộng tình huống, các sự kiện hoạt động sân bay trông như thế này:

{
  “flightNum”: 123,
  “carrierCode”: “JK”,
  “date”: “2024-01-25”,
  “event”: “FlightDelayed”,
  “message”: “Delayed 15 minutes, late aircraft”,
  “info”: “{ \”newDepTime\”: \”2024-01-25T13:15:00Z\”, \”delayMinutes\”: 15 }”
}

Các giá trị trong sự kiện xác định loại sự kiện và xem xét xem có liên quan đến hành khách hay không. Chi tiết sự kiện cung cấp thông tin thêm về sự kiện, thay đổi dựa trên loại sự kiện. Sân bay công bố một loạt các sự kiện nhưng sân bay chỉ hiển thị một phần nhỏ của những thay đổi đó.

AWS AppSync GraphQL APIs bắt đầu với một schema GraphQL xác định các loại, trường, và các hoạt động có sẵn trong API đó. Tài liệu AWS AppSync cung cấp một cái nhìn tổng quan về schema và các yếu tố cần thiết khác của GraphQL. Schema GraphQL một phần cho kịch bản sân bay như sau:

type DelayEventInfo implements EventInfo {
message: String
delayMinutes: Int
newDepTime: AWSDateTime
}

interface EventInfo {
message: String
}

enum StatusEvent {
FlightArrived
FlightBoarding
FlightCancelled
FlightDelayed
FlightGateChanged
FlightLanded
FlightPushBack
FlightTookOff
}

type StatusUpdate {
num: Int!
carrier: String!
date: AWSDate!
event: StatusEvent!
info: EventInfo
}

input StatusUpdateInput {
num: Int!
carrier: String!
date: AWSDate!
event: StatusEvent!
message: String
extra: AWSJSON
}

type Mutation {
updateFlightStatus(input: StatusUpdateInput!): StatusUpdate!
}

type Query {
listStatusUpdates(by: String): [StatusUpdate]
}

type Subscription {
onFlightStatusUpdate(date: AWSDate, carrier: String): StatusUpdate
@aws_subscribe(mutations: [“updateFlightStatus”])
}
schema {
query: Query
mutation: Mutation
subscription: Subscription
}

Kết nối EventBridge với AWS AppSync

EventBridge cho phép bạn lọc, biến đổi và định tuyến các sự kiện đến một số mục tiêu. Dịch vụ hiển thị sân bay chỉ cần những sự kiện ảnh hưởng trực tiếp đến hành khách. Bạn có thể xác định một quy tắc trong EventBridge để chỉ định đường dẫn những sự kiện đó (được bao gồm trong lược đồ GraphQL trước đó) đến mục tiêu AWS AppSync. Các sự kiện khác được định tuyến đến nơi khác, theo quy tắc khác, hoặc bị loại bỏ. Thông tin chi tiết về việc tạo quy tắc EventBridge và định dạng mẫu khớp sự kiện có thể được tìm thấy trong EventBridge documentation.

Sự kiện trễ chuyến bay trước đó sẽ được gửi bằng cách sử dụng EventBridge như sau:

{
  “id”: “b051312994104931b0980d1ad1c5340f”,
  “detail-type”: “Operations: Flight delayed”,
  “source”: “airport-operations”,
  “time”: “2024-01-25T16:58:37Z”,
  “detail”: {
    “flightNum”: 123,
    “carrierCode”: “JK”,
    “date”: “2024-01-25”,
    “event”: “FlightDelayed”,
    “message”: “Delayed 15 minutes, late aircraft”,
    “info”: “{ \”newDepTime\”: \”2024-01-25T13:15:00Z\”, \”delayMinutes\”: 15 }”
  }
}

Trong tình huống này, có một danh sách cụ thể các sự kiện quan trọng, nhưng EventBridge cung cấp một tập hợp linh hoạt các hoạt động để phù hợp với các mẫu, kiểm tra mảng và lọc theo nội dung bằng cách sử dụng tiền tố, số hoặc các phần khớp khác. Một số tổ chức cũng sẽ cho phép các bên đăng ký xác định các quy tắc của riêng mình trên một bus sự kiện EventBridge, cho phép các mục tiêu đăng ký theo dõi sự kiện thông qua các self-service.

Mẫu sự kiện sau khớp với các sự kiện cần thiết cho dịch vụ hiển thị sân bay:

{
  “source”: [ “airport-operations” ],
  “detail”: {
    “event”: [ “FlightArrived”, “FlightBoarding”, “FlightCancelled”, … ]
  }
}

Để tạo một EventBridge role mới, bạn có thể sử dụng AWS Management Console hoặc infrastructure as code. Bạn có thể tìm CloudFormation đã được tạo sẵn cho EventBridge role, với mục tiêu là AWS AppSync.

Console view

Tạo mục tiêu AWS AppSync

Bây giờ khi EventBridge được cấu hình để định tuyến các sự kiện được chọn, xác định AWS AppSync là mục tiêu. API AWS AppSync phải hỗ trợ xác thực IAM để được sử dụng làm mục tiêu của EventBridge. AWS AppSync hỗ trợ nhiều loại xác thực trên một loại GraphQL duy nhất, vì vậy bạn cũng có thể sử dụng OpenID Connect, Amazon Cognito User Pools hoặc các phương pháp xác thực khác cần thiết.

Để cấu hình AWS AppSync như một mục tiêu của EventBridge, xác định mục tiêu bằng cách sử dụng AWS Management Console hoặc infrastructure as code. Trong bảng điều khiển, chọn Target Type  là “AWS Service” và Mục tiêu là “AppSync.” Chọn API của bạn. EventBridge phân tích cú pháp GraphQL và cho phép bạn chọn mutation để gọi khi quy tắc được kích hoạt.

Khi sử dụng AWS Management Console, EventBridge cũng sẽ cấu hình AWS IAM role cần thiết để gọi ra biến đổi đã chọn. Hãy nhớ tạo và liên kết một vai trò với chính sách phù hợp khi cấu hình với IaC.

EventBridge hỗ trợ  input transformation để tùy chỉnh nội dung của một sự kiện trước khi chuyển thông tin đầu vào cho mục tiêu. Cấu hình bộ biến đổi đầu vào để trích xuất các giá trị cần thiết từ sự kiện bằng JSON path và các mẫu trong định dạng đầu vào được mong đợi bởi AWS AppSync API. EventBridge cung cấp một tiện ích hữu ích trong Console  để chuyển và kiểm tra đầu ra của một sự kiện mẫu.

Cuối cùng, cấu hình tập hợp lựa chọn để bao gồm phản hồi từ AWS AppSync API. Đây là các trường sẽ được trả về cho EventBridge khi mutation được gọi. Mặc dù kết quả trả về cho EventBridge không quá hữu ích (ngoại trừ việc sửa lỗi), tập hợp lựa chọn mutation cũng sẽ xác định các trường có sẵn cho các bên đăng ký đến đăng ký onFlightStatusUpdate.

Define the EventBridge to AWS AppSync rule in CloudFormation

Các mẫu Infrastructure as code như AWS CloudFormationAWS CDK rất hữu ích để chuyển đổi các định nghĩa cơ sở về hạ tầng để triển khai trên các Regions và tài khoản. Mặc dù bạn có thể viết CloudFormation bằng tay, EventBridge cung cấp một tính năng xuất CloudFormation hữu ích trong AWS Management Console. Bạn có thể sử dụng tính năng này để tạo định nghĩa cho một quy tắc đã được xác định.

Đây là CloudFormation cho quy tắc đã được cấu hình sẵn và mục tiêu AWS AppSync. Đoạn mã này bao gồm cả định nghĩa quy tắc và cấu hình mục tiêu.

PassengerEventsToDisplayServiceRule:
    Type: AWS::Events::Rule
    Properties:
      Description: Route passenger related events to the display service endpoint
      EventBusName: eb-to-appsync
      EventPattern:
        source:
          – airport-operations
        detail:
          event:
            – FlightArrived
            – FlightBoarding
            – FlightCancelled
            – FlightDelayed
            – FlightGateChanged
            – FlightLanded
            – FlightPushBack
            – FlightTookOff
      Name: passenger-events-to-display-service
      State: ENABLED
      Targets:
        – Id: 12344535353263463
          Arn: <AppSync API GraphQL API ARN>
          RoleArn: <EventBridge Role ARN (defined elsewhere)>
          InputTransformer:
            InputPathsMap:
              carrier: $.detail.carrierCode
              date: $.detail.date
              event: $.detail.event
              extra: $.detail.info
              message: $.detail.message
              num: $.detail.flightNum
            InputTemplate: |-
              {
                “input”: {
                  “num”: <num>,
                  “carrier”: <carrier>,
                  “date”: <date>,
                  “event”: <event>,
                  “message”: “<message>”,
                  “extra”: <extra>
                }
              }
          AppSyncParameters:
            GraphQLOperation: >-
              mutation
              UpdateFlightStatus($input:StatusUpdateInput!){updateFlightStatus(input:$input){
                event
                date
                carrier
                num
                info {
                  __typename
                  … on DelayEventInfo {
                    message
                    delayMinutes
                    newDepTime
                  }
                }
              }}

ARN của AWS AppSync API theo dạng arn:aws:appsync:<AWS_REGION>:<ACCOUNT_ID>:endpoints/graphql-api/<GRAPHQL_ENDPOINT_ID>. 

ARN có sẵn trong CloudFormation (xem giá trị trả về của GraphQLEndpointArn) hoặc có thể được tạo bằng cách sử dụng định danh được tìm thấy trong GraphQL endpoint của AWS AppSync

AppSyncParameters bao gồm hoạt động GraphQL mà EventBridge sẽ gọi trên API AWS AppSync. Điều này phải được định dạng đúng và phải khớp với schema GraphQL. Bao gồm bất kỳ trường nào cần phải có sẵn cho các service đã đăng ký.

Testing subscriptions

AWS AppSync hiện đã được cấu hình như một mục tiêu cho EventBridge rule. Ứng dụng hiển thị thực tế sẽ sử dụng một thư viện GraphQL, chẳng hạn như AWS Amplify, để đăng ký nhận thông báo về các thay đổi dữ liệu thời gian thực. AWS Management Console cung cấp một vài tiện ích hữu ích để kiểm tra. Di chuyển đến bảng điều khiển AWS AppSync console  và chọn Queries  trong menu API của bạn. Nhập truy vấn sau và chọn Run để các service đăng ký nhận thông báo về các thay đổi dữ liệu.

subscription MySubscription {
  onFlightStatusUpdate {
    carrier
    date
    event
    num
    info {
      __typename
      … on DelayEventInfo {
        message
        delayMinutes
        newDepTime
      }
    }
  }
}

Trong một tab trình duyệt khác, chuyển đến trang EventBridge và chọn Send events. Ở trang Send events , chọn bus sự kiện cần thiết và đặt Event source thành  “airport-operations.” Sau đó nhập một loại chi tiết theo sở thích của bạn. Cuối cùng, điền nội dung sau sau đó chọn Send.

{
  “id”: “b051312994104931b0980d1ad1c5340f”,
  “detail-type”: “Operations: Flight delayed”,
  “source”: “airport-operations”,
  “time”: “2024-01-25T16:58:37Z”,
  “detail”: {
    “flightNum”: 123,
    “carrierCode”: “JK”,
    “date”: “2024-01-25”,
    “event”: “FlightDelayed”,
    “message”: “Delayed 15 minutes, late aircraft”,
    “info”: “{ \”newDepTime\”: \”2024-01-25T13:15:00Z\”, \”delayMinutes\”: 15 }”
  }
}

Quay trở lại tab AWS AppSync trong trình duyệt của bạn để xem dữ liệu đã thay đổi trong ô kết quả:

Kết luận

Kích hoạt mục tiêu API GraphQL của AWS AppSync từ EventBridge giúp đơn giản hóa và tối ưu hóa tích hợp giữa hai dịch vụ này, lý tưởng để thông báo cho nhiều người đăng ký về các thay đổi dữ liệu trong các khối lượng công việc dựa trên sự kiện. Bạn cũng có thể tận dụng các tính năng khác có sẵn từ hai dịch vụ. Ví dụ, sử dụng bộ lọc đăng ký nâng cao của AWS AppSync để chỉ cập nhật các hiển thị sân bay trong nhà ga mà chúng được đặt.

Để tìm hiểu thêm về serverless, hãy truy cập Serverless Land để khám phá một loạt các mẫu có thể tái sử dụng, hướng dẫn và tài liệu học tập. Một mẫu mới được thêm vào thư viện mẫu là mẫu EventBridge to AWS AppSync tương tự như mô tả trong bài viết này. Truy cập EventBridge để biết thêm chi tiết.

Leave a comment