<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Tris Duong</title>
    <description>The latest articles on DEV Community by Tris Duong (@trisduong).</description>
    <link>https://dev.to/trisduong</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F585853%2Fc1c642c7-ef39-4488-8651-dc01eca9d5a2.jpeg</url>
      <title>DEV Community: Tris Duong</title>
      <link>https://dev.to/trisduong</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/trisduong"/>
    <language>en</language>
    <item>
      <title>Streamlining Workflows: Migrating from ECS and Fargate to Step Functions on AWS</title>
      <dc:creator>Tris Duong</dc:creator>
      <pubDate>Sat, 01 Jul 2023 07:22:29 +0000</pubDate>
      <link>https://dev.to/trisduong/streamlining-workflows-migrating-from-ecs-and-fargate-to-step-functions-on-aws-2b0o</link>
      <guid>https://dev.to/trisduong/streamlining-workflows-migrating-from-ecs-and-fargate-to-step-functions-on-aws-2b0o</guid>
      <description>&lt;p&gt;Introduction:&lt;br&gt;
As organizations strive to optimize their workflows and improve operational efficiency, they often turn to serverless technologies on the cloud. AWS offers a range of services that enable seamless orchestration of tasks and workflows. In this article, we will explore the journey of migrating from ECS (Elastic Container Service) and Fargate to Step Functions on AWS, highlighting the advantages and demonstrating the depth of AWS expertise and knowledge.&lt;/p&gt;

&lt;p&gt;Understanding ECS and Fargate:&lt;br&gt;
ECS and Fargate are popular container orchestration services on AWS. ECS allows users to run and manage containers using EC2 instances, providing granular control over the infrastructure. Fargate, on the other hand, abstracts away the underlying infrastructure and allows users to focus solely on running containers, making it a serverless option for container deployment.&lt;/p&gt;

&lt;p&gt;The Power of Step Functions:&lt;br&gt;
AWS Step Functions is a serverless workflow service that enables the coordination and sequencing of multiple AWS services and custom code to build scalable and resilient workflows. Step Functions utilizes visual workflows, state machines, and reliable error handling to simplify the process of designing and orchestrating complex workflows.&lt;/p&gt;

&lt;p&gt;Benefits of Migrating to Step Functions:&lt;/p&gt;

&lt;p&gt;Enhanced Workflow Management: Step Functions provides a powerful graphical interface for designing workflows, making it easier to visualize and manage complex sequences of tasks.&lt;br&gt;
Error Handling and Retry Mechanisms: Step Functions automatically handles errors and retries failed tasks, ensuring robustness and fault tolerance in workflows.&lt;br&gt;
Scalability and Flexibility: Step Functions can dynamically scale based on the workload, allowing organizations to handle variable workloads efficiently.&lt;br&gt;
Integration with AWS Services: Step Functions seamlessly integrates with various AWS services, enabling organizations to leverage the full potential of the AWS ecosystem in their workflows.&lt;br&gt;
Migration Process:&lt;br&gt;
Migrating from ECS and Fargate to Step Functions involves the following steps:&lt;br&gt;
Analyze Existing Workflows: Understand the current workflows and identify the dependencies between tasks.&lt;br&gt;
Design Step Functions State Machine: Use the visual interface of Step Functions to design the state machine, defining the sequence of tasks and their dependencies.&lt;br&gt;
Convert ECS/Fargate Tasks to Step Functions Tasks: Map the existing tasks in ECS/Fargate to equivalent tasks in Step Functions, ensuring the same functionality and dependencies are maintained.&lt;br&gt;
Implement Error Handling and Retries: Configure error handling and retry mechanisms within the Step Functions state machine to ensure resilience and fault tolerance.&lt;br&gt;
Test and Iterate: Thoroughly test the migrated workflows and iterate as necessary to optimize performance and reliability.&lt;br&gt;
Demonstrating AWS Expertise and Knowledge:&lt;br&gt;
Migrating from ECS and Fargate to Step Functions showcases a deep understanding of AWS services and the ability to leverage them effectively. It requires proficiency in containerization, workflow design, error handling, and service integration. By successfully executing this migration, organizations can demonstrate their expertise in AWS architecture, serverless computing, and workflow management.&lt;br&gt;
Conclusion:&lt;br&gt;
Migrating from ECS and Fargate to Step Functions on AWS represents a significant step towards streamlining workflows and optimizing operational efficiency. This migration showcases the power of AWS services, highlighting the depth of knowledge and expertise in leveraging cloud-based technologies. By embracing Step Functions, organizations can unlock enhanced workflow management capabilities and pave the way for scalable and resilient business processes.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Tutorial Use AWS EventBridge and AppSync for Real-time Notification to Client-side</title>
      <dc:creator>Tris Duong</dc:creator>
      <pubDate>Sat, 01 Jul 2023 06:50:19 +0000</pubDate>
      <link>https://dev.to/trisduong/tutorial-use-aws-eventbridge-and-appsync-for-real-time-notification-to-client-side-405a</link>
      <guid>https://dev.to/trisduong/tutorial-use-aws-eventbridge-and-appsync-for-real-time-notification-to-client-side-405a</guid>
      <description>&lt;h1&gt;
  
  
  Introduction:
&lt;/h1&gt;

&lt;p&gt;Real-time notifications are becoming increasingly important for many&lt;br&gt;
applications, as users expect to be notified of important events as soon&lt;br&gt;
as they happen. AWS EventBridge and AWS AppSync can be powerful tools to&lt;br&gt;
accomplish this goal with minimal cost. In this summary, I will walk&lt;br&gt;
through the setup of a demo application that uses EventBridge and&lt;br&gt;
AppSync to provide real-time updates to a client-side web application&lt;br&gt;
and the cost-saving analyst.&lt;/p&gt;

&lt;h1&gt;
  
  
  AWS EventBridge:
&lt;/h1&gt;

&lt;p&gt;AWS EventBridge is a powerful event bus service offered by Amazon Web&lt;br&gt;
Services (AWS) that enables users to build real-time applications that&lt;br&gt;
respond to data changes. With EventBridge, developers can set up rules&lt;br&gt;
to route events from different sources, including AWS services,&lt;br&gt;
third-party software-as-a-service (SaaS) applications, and custom&lt;br&gt;
applications, to one or more targets. Targets can include AWS services,&lt;br&gt;
such as AWS Lambda or Amazon SNS, as well as custom HTTP endpoints.&lt;/p&gt;

&lt;p&gt;One of the main benefits of using AWS EventBridge is its ability to&lt;br&gt;
simplify event-driven architectures. Instead of creating custom code to&lt;br&gt;
handle each event source, developers can use EventBridge to route events&lt;br&gt;
to the right targets automatically. This not only reduces the amount of&lt;br&gt;
code required but also makes it easier to scale and manage applications.&lt;br&gt;
Additionally, EventBridge provides built-in security features, such as&lt;br&gt;
encryption and access control, to ensure that event data is secure and&lt;br&gt;
compliant.&lt;/p&gt;

&lt;h1&gt;
  
  
  AWS AppSync:
&lt;/h1&gt;

&lt;p&gt;AWS AppSync is a managed service provided by AWS that simplifies the&lt;br&gt;
process of building scalable GraphQL APIs. With AppSync, developers can&lt;br&gt;
define and map a data schema to one or more data sources, such as AWS&lt;br&gt;
DynamoDB or AWS Lambda functions. AppSync then automatically generates&lt;br&gt;
GraphQL APIs that can be accessed by client-side applications.&lt;/p&gt;

&lt;p&gt;One of the key features of AppSync is its ability to support real-time&lt;br&gt;
updates through subscriptions. With subscriptions, client-side&lt;br&gt;
applications can receive real-time updates when data changes. AppSync&lt;br&gt;
supports three types of subscriptions: on-demand, real-time, and hybrid.&lt;br&gt;
On-demand subscriptions are triggered by client requests, while&lt;br&gt;
real-time subscriptions are pushed by the server when data changes.&lt;br&gt;
Hybrid subscriptions combine both on-demand and real-time subscriptions&lt;br&gt;
to provide a more flexible approach.&lt;/p&gt;

&lt;p&gt;Additionally, AppSync provides features to simplify data&lt;br&gt;
synchronization, offline data access, and conflict resolution. These&lt;br&gt;
features make it easier to build scalable and reliable applications that&lt;br&gt;
work seamlessly across different devices and network conditions.&lt;/p&gt;

&lt;h1&gt;
  
  
  Setting Up the Demo Application:
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9ngodj6s54nidy167wiw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9ngodj6s54nidy167wiw.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Create an EventBridge Rule:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Go to the EventBridge console&lt;/li&gt;
&lt;li&gt;  Click on \"Create Rule\"&lt;/li&gt;
&lt;li&gt;  Enter a name for the rule and a description (optional)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft53flu978zewt8ywbdto.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft53flu978zewt8ywbdto.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-   Under \"Event Pattern\", choose \"Custom Pattern\"

-   In the \"Event Pattern\" text area, enter the following pattern
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

{\"detail-type\": \[\"Cloud Notification\"\]}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffn9kj5h84r1sw4s0bys9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffn9kj5h84r1sw4s0bys9.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-   This pattern will match all events with the detail-type \"Cloud
    Notification\". We can use multiple patterns for each type of
    notification if we want.

-   Click on \"Create a new API destination\"

-   Choose "Create a new connection"

-   Enter a name for the connection and a description (optional)

-   Under \"Endpoint URL\", enter the AppSync endpoint URL

-   Choose the authentication method (API Key or Basic
    (Username/Password) or OAuth Client Credentials ). We can use
    OAuth Client of the Cloud side.

-   Click on "Additional settings" and choose "Configure
    transformer". This step will transform data of the event bridge
    to body data that need when post to GraphQL. We also can add
    data that we need in this step. It is very flexible.

-   Fill in "Target input transformer":
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

{\"message\":\"\$.detail.message\",\"resourceId\":\"\$.detail.resource-id\",\"resourceType\":\"\$.detail.resource-type\",\"updatedAt\":\"\$.time\",\"userId\":\"\$.detail.user-id\"}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-   Fill in "Template":
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

{
  "query": "mutation PublishNotification($userId: ID!, $resourceId: ID!, $resourceType: String!, $message: String!, $updatedAt: AWSDateTime!) { publishNotification(userId: $userId, resourceId: $resourceId, resourceType: $resourceType, message: $message, updatedAt: $updatedAt) { userId resourceId resourceType message updatedAt } }",
  "operationName": "PublishNotification",
  "variables": {
    "userId": "&amp;lt;userId&amp;gt;",
    "resourceId": "&amp;lt;resourceId&amp;gt;",
    "resourceType": "&amp;lt;resourceType&amp;gt;",
    "message": "&amp;lt;message&amp;gt;",
    "updatedAt": "&amp;lt;updatedAt&amp;gt;"
  }
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-   Click on \"Create\"

&amp;gt; Now, all events with the detail-type 
\"Cloud Notification\" will be
&amp;gt; sent to the destination that you selected.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Create an AppSync API:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Go to the AppSync console&lt;/li&gt;
&lt;li&gt;  Click on \"Create API\"&lt;/li&gt;
&lt;li&gt;  Choose \"Build from scratch\"&lt;/li&gt;
&lt;li&gt;  Enter a name for the API&lt;/li&gt;
&lt;li&gt;  Click on "Create"&lt;/li&gt;
&lt;li&gt;  Click on "Edit Schema" and use this example schema:&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

type Mutation {
    publishNotification(
        userId: ID!,
        resourceId: ID!,
        resourceType: String!,
        message: String!,
        updatedAt: AWSDateTime!
    ): Notification
}

type Notification {
    userId: ID!
    resourceId: ID!
    resourceType: String!
    message: String!
    updatedAt: AWSDateTime!
}

type Query {
    getNotification: Notification
}

type Subscription {
    onNotification(userId: ID!): Notification
        @aws_subscribe(mutations: ["publishNotification"])
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-   Under \"Data sources\", click on \"Create data source\"

-   Choose \"None\" as the data source( We can save notifications to
    a database if need, I chose "None" to not save)

-   Enter a name for the data source and a description (optional)

-   Under \"Resolver\" of mutation "publishNotification", click on
    \"Attach\"

-   Choose \"Create a new resolver\"

-   Enter a name for the resolver and a description (optional)

-   Under \"Data source\", choose the data source that you created

-   Under \"Request mapping template\", enter the following
    template:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

{
  "version": "2023-03-21",
  "payload": $util.toJson($context.args)
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-   This template will transform the event data into a format that
    can be used by the AppSync resolver.

-   Under \"Response mapping template\", enter the following
    template:

-   \$util.toJson(\$context.result)



-   This template will transform the AppSync resolver response to a
    format that the client-side application can use.

    -   Click on \"Create\"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;I have created an AppSync API with a resolver that can process events&lt;br&gt;
from the EventBridge.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Create a client-side application:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Create a new project using your preferred client-side framework
(React, Angular, etc.)&lt;/li&gt;
&lt;li&gt;  Install the AWS Amplify library&lt;/li&gt;
&lt;li&gt;  Configure the Amplify library with your AppSync endpoint URL and
authentication method&lt;/li&gt;
&lt;li&gt;  In your application code, create a subscription to the AppSync
API using the Amplify library&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

import { API, graphqlOperation } from 'aws-amplify';
import { onCreateNotification } from './graphql/subscriptions';

API.graphql(graphqlOperation(onCreateNotification, { userId: '123' }))
  .subscribe({
    next: (notification) =&amp;gt; {
      console.log(notification);
    },
    error: (error) =&amp;gt; {
      console.log(error);
    }
  });



&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;This code will subscribe to the AppSync API and receive real-time&lt;br&gt;
notifications whenever a new notification is created for the user with&lt;br&gt;
ID \"123\".&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Create a client-side application with python:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Client code example to receive notification:&lt;/li&gt;
&lt;li&gt;  # subscription_client.py&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;
&lt;br&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
&lt;h1&gt;
  
  
  subscription_client.py
&lt;/h1&gt;

&lt;p&gt;from base64 import b64encode, decode&lt;br&gt;
from datetime import datetime&lt;br&gt;
from uuid import uuid4&lt;/p&gt;

&lt;p&gt;import websocket&lt;br&gt;
import threading&lt;br&gt;
import ssl&lt;/p&gt;

&lt;p&gt;import json&lt;/p&gt;
&lt;h1&gt;
  
  
  Constants Copied from AppSync API 'Settings'
&lt;/h1&gt;

&lt;p&gt;API_URL = &amp;lt;YOUR_API_URL&amp;gt;&lt;br&gt;
API_KEY = &amp;lt;YOUR_API_KEY&amp;gt;&lt;/p&gt;

&lt;p&gt;USER_ID = &amp;lt;YOUR_USER_ID_WANT_TO_SEND_NOTIFICATION&amp;gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  GraphQL subscription Registration object
&lt;/h1&gt;

&lt;p&gt;GQL_SUBSCRIPTION = json.dumps({&lt;br&gt;
    "query": """&lt;br&gt;
    subscription($userId: ID!) {&lt;br&gt;
      onNotification(userId: $userId) {&lt;br&gt;
        userId&lt;br&gt;
        resourceId&lt;br&gt;
        resourceType&lt;br&gt;
        message&lt;br&gt;
        updatedAt&lt;br&gt;
      }&lt;br&gt;
    }&lt;br&gt;
    """,&lt;br&gt;
    "variables": {&lt;br&gt;
        "userId": USER_ID&lt;br&gt;
    }&lt;br&gt;
})&lt;/p&gt;
&lt;h1&gt;
  
  
  Discovered values from the AppSync endpoint (API_URL)
&lt;/h1&gt;

&lt;p&gt;WSS_URL = API_URL.replace('https', 'wss').replace('appsync-api', 'appsync-realtime-api')&lt;br&gt;
HOST = API_URL.replace('https://', '').replace('/graphql', '')&lt;/p&gt;
&lt;h1&gt;
  
  
  Subscription ID (client generated)
&lt;/h1&gt;

&lt;p&gt;SUB_ID = str(uuid4())&lt;/p&gt;
&lt;h1&gt;
  
  
  Set up Timeout Globals
&lt;/h1&gt;

&lt;p&gt;timeout_timer = None&lt;br&gt;
timeout_interval = 10&lt;/p&gt;
&lt;h1&gt;
  
  
  Calculate UTC time in ISO format (AWS Friendly): YYYY-MM-DDTHH:mm:ssZ
&lt;/h1&gt;

&lt;p&gt;def header_time():&lt;br&gt;
    return datetime.utcnow().isoformat(sep='T', timespec='seconds') + 'Z'&lt;/p&gt;
&lt;h1&gt;
  
  
  Encode Using Base 64
&lt;/h1&gt;

&lt;p&gt;def header_encode(header_obj):&lt;br&gt;
    return b64encode(json.dumps(header_obj).encode('utf-8')).decode('utf-8')&lt;/p&gt;
&lt;h1&gt;
  
  
  reset the keep alive timeout daemon thread
&lt;/h1&gt;

&lt;p&gt;def reset_timer(ws):&lt;br&gt;
    global timeout_timer&lt;br&gt;
    global timeout_interval&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if (timeout_timer):
    timeout_timer.cancel()
timeout_timer = threading.Timer(timeout_interval, lambda: ws.close())
timeout_timer.daemon = True
timeout_timer.start()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h1&gt;
  
  
  Create API key authentication header
&lt;/h1&gt;

&lt;p&gt;api_header = {&lt;br&gt;
    'host': HOST,&lt;br&gt;
    'x-api-key': API_KEY&lt;br&gt;
}&lt;/p&gt;
&lt;h1&gt;
  
  
  Socket Event Callbacks, used in WebSocketApp Constructor
&lt;/h1&gt;

&lt;p&gt;def on_message(ws, message):&lt;br&gt;
    global timeout_timer&lt;br&gt;
    global timeout_interval&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;print('### message ###')
print('&amp;amp;lt;&amp;amp;lt; ' + message)

message_object = json.loads(message)
message_type = message_object['type']

if (message_type == 'ka'):
    reset_timer(ws)

elif (message_type == 'connection_ack'):
    timeout_interval = int(json.dumps(message_object['payload']['connectionTimeoutMs']))

    register = {
        'id': SUB_ID,
        'payload': {
            'data': GQL_SUBSCRIPTION,
            'extensions': {
                'authorization': {
                    'host': HOST,
                    'x-api-key': API_KEY
                }
            }
        },
        'type': 'start'
    }
    start_sub = json.dumps(register)
    print('&amp;amp;gt;&amp;amp;gt; ' + start_sub)
    ws.send(start_sub)

elif (message_type == 'data'):
    deregister = {
        'type': 'stop',
        'id': SUB_ID
    }
    end_sub = json.dumps(deregister)
    print('&amp;amp;gt;&amp;amp;gt; ' + end_sub)
    ws.send(end_sub)

elif (message_object['type'] == 'error'):
    print('Error from AppSync: ' + message_object['payload'])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;def on_error(ws, error):&lt;br&gt;
    print('### error ###')&lt;br&gt;
    print(error)&lt;/p&gt;

&lt;p&gt;def on_close(ws):&lt;br&gt;
    print('### closed ###')&lt;/p&gt;

&lt;p&gt;def on_open(ws):&lt;br&gt;
    print('### opened ###')&lt;br&gt;
    init = {&lt;br&gt;
        'type': 'connection_init'&lt;br&gt;
    }&lt;br&gt;
    init_conn = json.dumps(init)&lt;br&gt;
    print('&amp;gt;&amp;gt; ' + init_conn)&lt;br&gt;
    ws.send(init_conn)&lt;/p&gt;

&lt;p&gt;if &lt;strong&gt;name&lt;/strong&gt; == '&lt;strong&gt;main&lt;/strong&gt;':&lt;br&gt;
    # Uncomment to see socket bytestreams&lt;br&gt;
    # websocket.enableTrace(True)&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Set up the connection URL, which includes the Authentication Header
#   and a payload of '{}'.  All info is base 64 encoded
connection_url = WSS_URL + '?header=' + header_encode(api_header) + '&amp;amp;amp;payload=e30='

# Create the websocket connection to AppSync's real-time endpoint
#  also defines callback functions for websocket events
#  NOTE: The connection requires a subprotocol 'graphql-ws'
print('Connecting to: ' + connection_url)

ws = websocket.WebSocketApp(connection_url,
                            subprotocols=['graphql-ws'],
                            on_open=on_open,
                            on_message=on_message,
                            on_error=on_error,
                            on_close=on_close, )

ws.run_forever(sslopt={"cert_reqs": ssl.CERT_NONE, "ssl_version": ssl.PROTOCOL_TLSv1_2})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-   Server code example to send notifications:&lt;br&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

&lt;p&gt;import boto3&lt;br&gt;
import json&lt;/p&gt;

&lt;p&gt;event_bridge = boto3.client('events')&lt;/p&gt;
&lt;h1&gt;
  
  
  Define the event details
&lt;/h1&gt;

&lt;p&gt;event = {&lt;br&gt;
    "detail-type": "Cloud Notification",&lt;br&gt;
    "source": "experiments.created",&lt;br&gt;
    "detail": {&lt;br&gt;
        "user-id": "123",&lt;br&gt;
        "resource-id": "345",&lt;br&gt;
        "resource-type": "experiments",&lt;br&gt;
        "message": "created successful"&lt;br&gt;
    }&lt;br&gt;
}&lt;/p&gt;
&lt;h1&gt;
  
  
  Put the event to EventBridge
&lt;/h1&gt;

&lt;p&gt;response = event_bridge.put_events(&lt;br&gt;
    Entries=[&lt;br&gt;
        {&lt;br&gt;
            'Source': event['source'],&lt;br&gt;
            'DetailType': event['detail-type'],&lt;br&gt;
            'Detail': json.dumps(event['detail']),&lt;br&gt;
            'EventBusName': 'notification'&lt;br&gt;
        }&lt;br&gt;
    ]&lt;br&gt;
)&lt;/p&gt;
&lt;h1&gt;
  
  
  Check the response
&lt;/h1&gt;

&lt;p&gt;print(response)&lt;/p&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  Demo success screenshot:&lt;br&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdtl2oj3vlxrsddhm82gt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdtl2oj3vlxrsddhm82gt.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Cost analyst:
&lt;/h1&gt;

&lt;p&gt;One potential challenge when building a real-time notification system is&lt;br&gt;
managing costs. Fortunately, using AWS EventBridge and AWS AppSync can&lt;br&gt;
be a cost-effective option. Both services offer a pay-as-you-go pricing&lt;br&gt;
model, which means you only pay for the resources you use. Additionally,&lt;br&gt;
both services require minimal setup and maintenance and offer automatic&lt;br&gt;
scaling to optimize resource usage. By leveraging these services, you&lt;br&gt;
can reduce operational costs and benefit from integration with other AWS&lt;br&gt;
services.&lt;/p&gt;

&lt;p&gt;The cost of using AWS EventBridge and AWS AppSync can vary depending on&lt;br&gt;
the usage patterns of your application. AWS EventBridge charges per&lt;br&gt;
event processed, with a tiered pricing model that offers reduced rates&lt;br&gt;
for higher volume usage. AWS AppSync charges based on the number of API&lt;br&gt;
requests and data transfers, with the first 1 million API requests per&lt;br&gt;
month being free. Data transfer costs start at \$0.15 per GB per month.&lt;/p&gt;

&lt;p&gt;An example cost breakdown for an application that processes 1 million&lt;br&gt;
events per month and makes 1 million API requests per month, with 100 GB&lt;br&gt;
of data transfer, would be \$20.00 per month.&lt;/p&gt;

&lt;h1&gt;
  
  
  Best Practices:
&lt;/h1&gt;

&lt;p&gt;When building a real-time notification system using AWS EventBridge and&lt;br&gt;
AppSync, several best practices can help ensure scalability,&lt;br&gt;
reliability, and security. Some key best practices include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Use fine-grained events: By using fine-grained events, you can&lt;br&gt;
reduce the amount of data sent to EventBridge and improve the&lt;br&gt;
efficiency of the notification system.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use dead-letter queues: Dead-letter queues can be used to capture&lt;br&gt;
failed events and investigate any issues that occur. This can help&lt;br&gt;
prevent data loss and ensure the notification system works properly.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use caching: Caching can help reduce the number of requests sent to&lt;br&gt;
data sources, improving the efficiency of the notification system.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Monitor and troubleshoot: It\'s important to monitor the&lt;br&gt;
notification system and troubleshoot any issues that arise. AWS&lt;br&gt;
provides tools like CloudWatch and X-Ray to help with monitoring and&lt;br&gt;
troubleshooting.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use encryption and access control: Encryption and access control&lt;br&gt;
should be used to ensure that event data is secure and compliant&lt;br&gt;
with regulatory requirements. AWS provides features like AWS KMS and&lt;br&gt;
IAM to help with encryption and access control.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Conclusion:
&lt;/h1&gt;

&lt;p&gt;In conclusion, using AWS EventBridge and AWS AppSync can be a&lt;br&gt;
cost-effective solution for building a real-time notification system. By&lt;br&gt;
leveraging these services, We can reduce operational costs, take&lt;br&gt;
advantage of cost-effective scaling, and benefit from integration with&lt;br&gt;
other AWS services. With the steps and best practices covered in this&lt;br&gt;
summary, We can build a scalable and reliable real-time notification&lt;br&gt;
system that meets the needs of our users.&lt;/p&gt;

&lt;h1&gt;
  
  
  References:
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://aws.amazon.com/blogs/mobile/appsync-eventbridge/" rel="noopener noreferrer"&gt;https://aws.amazon.com/blogs/mobile/appsync-eventbridge/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.aws.amazon.com/appsync/latest/devguide/real-time-websocket-client.html" rel="noopener noreferrer"&gt;https://docs.aws.amazon.com/appsync/latest/devguide/real-time-websocket-client.html&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Elevate Your Development Workflow with AWS: Best Practices for Dev Tools</title>
      <dc:creator>Tris Duong</dc:creator>
      <pubDate>Sat, 01 Jul 2023 06:33:45 +0000</pubDate>
      <link>https://dev.to/trisduong/elevate-your-development-workflow-with-aws-best-practices-for-dev-tools-3j1o</link>
      <guid>https://dev.to/trisduong/elevate-your-development-workflow-with-aws-best-practices-for-dev-tools-3j1o</guid>
      <description>&lt;p&gt;In today's fast-paced software development landscape, utilizing the right set of development tools is critical to ensure efficiency, collaboration, and scalability. Amazon Web Services (AWS) provides a comprehensive suite of development tools that enhance the software development lifecycle, enabling teams to build, test, and deploy applications seamlessly. In this article, we will delve into the best practices for using AWS dev tools, showcasing AWS's experience and expertise in empowering developers to streamline their development workflows and deliver high-quality applications.&lt;/p&gt;

&lt;p&gt;Version Control with AWS CodeCommit:&lt;br&gt;
Version control is essential for collaborative development. AWS CodeCommit provides a fully managed Git-based version control service that integrates seamlessly with popular Git clients. Best practices include using separate branches for feature development, bug fixes, and release management. Utilizing CodeCommit's access control policies ensures secure collaboration within development teams while maintaining code integrity.&lt;/p&gt;

&lt;p&gt;Continuous Integration and Delivery with AWS CodePipeline:&lt;br&gt;
Implementing continuous integration and delivery (CI/CD) pipelines is crucial for automating the build, test, and deployment process. AWS CodePipeline enables developers to define a pipeline that automatically orchestrates code changes from source control to production. Best practices involve breaking down the pipeline into smaller, easily testable stages, and utilizing AWS CodeBuild and AWS CodeDeploy for efficient and reliable application deployment.&lt;/p&gt;

&lt;p&gt;Infrastructure as Code with AWS CloudFormation:&lt;br&gt;
AWS CloudFormation allows developers to define and provision infrastructure resources in a declarative manner. Embracing infrastructure as code (IaC) practices ensures consistency, repeatability, and scalability. Best practices include creating reusable templates, parameterizing resource configurations, and leveraging AWS CloudFormation StackSets for managing resources across multiple accounts and regions.&lt;/p&gt;

&lt;p&gt;Testing and QA with AWS Device Farm:&lt;br&gt;
With the increasing diversity of devices and platforms, comprehensive testing is crucial. AWS Device Farm provides a cloud-based testing service that allows developers to test their applications on real devices. Best practices involve creating test suites that cover different device configurations and utilizing AWS Device Farm's automated testing capabilities to improve test coverage and accelerate release cycles.&lt;/p&gt;

&lt;p&gt;Monitoring and Troubleshooting with AWS X-Ray:&lt;br&gt;
Monitoring and troubleshooting are essential for maintaining application performance and reliability. AWS X-Ray provides end-to-end visibility into application behavior, enabling developers to identify bottlenecks, trace requests, and analyze performance. Best practices include instrumenting applications with X-Ray SDKs, utilizing service maps to visualize dependencies, and setting up alarms based on critical metrics for proactive monitoring and issue resolution.&lt;/p&gt;

&lt;p&gt;Secure Secrets Management with AWS Secrets Manager:&lt;br&gt;
Managing application secrets securely is crucial to protect sensitive data. AWS Secrets Manager offers a centralized solution for securely storing and managing secrets. Best practices involve rotating secrets regularly, granting least privilege access using IAM policies, and integrating Secrets Manager with other AWS services like AWS Lambda for secure and automated secret retrieval.&lt;/p&gt;

&lt;p&gt;Conclusion:&lt;br&gt;
AWS's extensive range of development tools empowers developers to streamline their workflows, enhance collaboration, and deliver high-quality applications efficiently. By following best practices such as utilizing AWS CodeCommit for version control, implementing CI/CD pipelines with AWS CodePipeline, leveraging infrastructure as code with AWS CloudFormation, conducting comprehensive testing with AWS Device Farm, monitoring applications with AWS X-Ray, and securely managing secrets with AWS Secrets Manager, developers can harness the full potential of AWS dev tools. As AWS continues to innovate in the realm of development, their expertise and comprehensive toolset remain indispensable for modern software development teams striving for agility, scalability, and reliability in their projects.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Mastering Serverless Best Practices with AWS: Unlocking the Full Potential</title>
      <dc:creator>Tris Duong</dc:creator>
      <pubDate>Sat, 01 Jul 2023 06:27:46 +0000</pubDate>
      <link>https://dev.to/trisduong/mastering-serverless-best-practices-with-aws-unlocking-the-full-potential-56hd</link>
      <guid>https://dev.to/trisduong/mastering-serverless-best-practices-with-aws-unlocking-the-full-potential-56hd</guid>
      <description>&lt;p&gt;Serverless computing has revolutionized the way developers build and deploy applications, offering scalability, cost-efficiency, and faster time-to-market. However, to fully leverage the power of serverless, it is crucial to adhere to best practices that ensure optimal performance, security, and maintainability. In this article, we will explore serverless best practices, showcasing AWS's extensive experience and knowledge in the realm of serverless architecture. By following these practices, developers can maximize the benefits of serverless computing while leveraging the advanced services and features offered by AWS.&lt;/p&gt;

&lt;p&gt;Function Design and Granularity:&lt;br&gt;
When designing serverless functions, it is important to follow the single-responsibility principle and keep functions small and focused. Breaking down complex tasks into smaller functions promotes reusability, enhances code maintainability, and allows for granular scaling. AWS Lambda, the serverless compute service, encourages this practice by providing fine-grained control over individual functions and their resources.&lt;/p&gt;

&lt;p&gt;Use Event-Driven Architecture:&lt;br&gt;
Serverless architectures excel in event-driven scenarios. Leveraging AWS EventBridge or AWS SNS (Simple Notification Service), developers can decouple components, allowing them to react to events, trigger workflows, and maintain loose coupling between services. This approach ensures scalability, resilience, and flexibility in responding to changing business requirements.&lt;/p&gt;

&lt;p&gt;Implement Security Best Practices:&lt;br&gt;
Security is of utmost importance in any application. With AWS, security features are built into the serverless services. Best practices include using AWS Identity and Access Management (IAM) roles to grant the least privilege principle to functions, encrypting sensitive data using AWS Key Management Service (KMS), and implementing secure communication protocols, such as HTTPS, for API Gateway endpoints. AWS also provides tools like AWS WAF (Web Application Firewall) and AWS Shield to protect against common web threats.&lt;/p&gt;

&lt;p&gt;Optimize Resource Allocation:&lt;br&gt;
Efficient resource allocation is crucial for cost optimization and performance. With AWS Lambda, developers can fine-tune memory allocation to optimize function performance. Properly configuring the memory allocation for each function ensures that you are not overpaying for unnecessary resources while achieving optimal execution times.&lt;/p&gt;

&lt;p&gt;Monitor and Debug:&lt;br&gt;
AWS offers powerful monitoring and logging services like AWS CloudWatch and AWS X-Ray. Implementing comprehensive monitoring and logging practices helps identify performance bottlenecks, track errors, and gain insights into application behavior. It is crucial to monitor key metrics, set up appropriate alerts, and use distributed tracing tools for effective debugging and troubleshooting.&lt;/p&gt;

&lt;p&gt;Automated Deployment and Infrastructure as Code:&lt;br&gt;
Adopting infrastructure as code (IaC) principles with tools like AWS CloudFormation or AWS Serverless Application Model (SAM) streamlines the deployment process, ensuring consistency and repeatability. By defining infrastructure and resources as code, developers can automate deployments, manage changes efficiently, and version control their infrastructure, promoting collaboration and reducing human error.&lt;/p&gt;

&lt;p&gt;Conclusion:&lt;br&gt;
AWS's expertise and comprehensive suite of serverless services empower developers to implement best practices and unlock the full potential of serverless computing. By adhering to function design principles, leveraging event-driven architectures, implementing robust security measures, optimizing resource allocation, and adopting monitoring and debugging practices, developers can build scalable, resilient, and cost-efficient serverless applications on AWS. Additionally, the adoption of automated deployment and infrastructure as code practices simplifies the development lifecycle, enabling faster iterations and smoother collaboration. As serverless continues to evolve, AWS remains at the forefront, providing developers with the tools and knowledge needed to succeed in the serverless era.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
