<?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: Dara Olayebi</title>
    <description>The latest articles on DEV Community by Dara Olayebi (@daraolayebi).</description>
    <link>https://dev.to/daraolayebi</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%2F826675%2F835a6a8c-37ce-4ab8-bed2-353607e38d56.JPG</url>
      <title>DEV Community: Dara Olayebi</title>
      <link>https://dev.to/daraolayebi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/daraolayebi"/>
    <language>en</language>
    <item>
      <title>This Week I Learnt: Java's CompletableFuture</title>
      <dc:creator>Dara Olayebi</dc:creator>
      <pubDate>Wed, 31 Jul 2024 19:18:43 +0000</pubDate>
      <link>https://dev.to/daraolayebi/this-week-i-learnt-completablefuture-javas-approach-to-asynchronous-programming-27ka</link>
      <guid>https://dev.to/daraolayebi/this-week-i-learnt-completablefuture-javas-approach-to-asynchronous-programming-27ka</guid>
      <description>&lt;p&gt;&lt;em&gt;This week, I'm diving into Java's CompletableFuture.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;As a full-stack developer with a frontend background, dealing with asynchronous tasks is an inevitable part of my role – network requests, background computations, and the like. In Java, &lt;code&gt;CompletableFuture&lt;/code&gt; is a powerful tool for handling these tasks while keeping the main thread responsive.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Completable futures are to Java what Promises are to JavaScript.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you're familiar with JavaScript, it might help to grasp these concepts by making parallels between both languages. I like to think of &lt;code&gt;CompletableFuture&lt;/code&gt; as Java's version of a &lt;code&gt;Promise&lt;/code&gt;. It is a class that represents the eventual result of an asynchronous operation, whether that result is a success or failure. Introduced in Java 8 as part of the &lt;code&gt;java.util.concurrent&lt;/code&gt; package, it's a powerful way of writing non-blocking code, with methods for chaining operations, and handling errors, similarly to Promises.&lt;/p&gt;

&lt;p&gt;Here's a quick comparison of the two:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// JavaScript Promise&lt;/span&gt;
&lt;span class="nf"&gt;fetchFromServer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;processData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;updateUI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;handleError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Java CompletableFuture&lt;/span&gt;
&lt;span class="nc"&gt;CompletableFuture&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;supplyAsync&lt;/span&gt;&lt;span class="o"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;fetchDataFromServer&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;thenApply&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;processData&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;thenAccept&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;updateUI&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;exceptionally&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;handleError&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As illustrated above, &lt;code&gt;CompletableFuture&lt;/code&gt; provides a similar, chainable syntax that allows for clean and readable asynchronous code.&lt;/p&gt;

&lt;p&gt;Consider a scenario where you need to fetch a user's profile data and order history from two separate endpoints. You would want to avoid freezing the UI while waiting for these requests to complete. Here's how you would implement this using &lt;code&gt;CompletableFuture&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;CompletableFuture&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;profileFuture&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;CompletableFuture&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;supplyAsync&lt;/span&gt;&lt;span class="o"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Fetch user profile from a service&lt;/span&gt;
&lt;span class="o"&gt;});&lt;/span&gt;

&lt;span class="nc"&gt;CompletableFuture&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Order&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ordersFuture&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;CompletableFuture&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;supplyAsync&lt;/span&gt;&lt;span class="o"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Fetch user orders from another service&lt;/span&gt;
&lt;span class="o"&gt;});&lt;/span&gt;

&lt;span class="nc"&gt;CompletableFuture&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Void&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;combinedFuture&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;CompletableFuture&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;allOf&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;profileFuture&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ordersFuture&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;combinedFuture&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;thenRun&lt;/span&gt;&lt;span class="o"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;User&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;userFuture&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;join&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt; 
    &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Order&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ordersFuture&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;join&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt; 
    &lt;span class="n"&gt;displayUserData&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; 
&lt;span class="o"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, we trigger two asynchronous requests simultaneously and use &lt;code&gt;allOf&lt;/code&gt; to wait for both to finish. Once they complete, we retrieve the results and update the UI accordingly, all without blocking the main thread.&lt;/p&gt;




&lt;h2&gt;
  
  
  Chaining &amp;amp; CompletionStage
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;CompletableFuture&lt;/code&gt; implements the &lt;code&gt;CompletionStage&lt;/code&gt; interface, which provides the foundation for chaining operations. Each &lt;code&gt;thenApply&lt;/code&gt;, &lt;code&gt;thenAccept&lt;/code&gt;, and similar method returns another CompletionStage, allowing you to create complex asynchronous pipelines.&lt;/p&gt;

&lt;p&gt;Similar to how we can chain promises in JavaScript when we have a sequence of asynchronous tasks to be performed one after another, we can chain tasks within a Completable Future in order to create a sequence of dependent asynchronous operations without falling into callback hell. Here's how we would do that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;CompletableFuture&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;supplyAsync&lt;/span&gt;&lt;span class="o"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"Hello"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;thenApply&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;", CompletableFuture"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;thenApply&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;" in Java"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;thenAccept&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;println&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Handling exceptions
&lt;/h2&gt;

&lt;p&gt;Where we have &lt;code&gt;.catch()&lt;/code&gt; on a Promise object, we have &lt;code&gt;.exceptionally()&lt;/code&gt; on a Completable Future. This method handles exceptions that may occur during asynchronous processing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;CompletableFuture&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;supplyAsync&lt;/span&gt;&lt;span class="o"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;RuntimeException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Exception in CompletableFuture!"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"No exception"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}).&lt;/span&gt;&lt;span class="na"&gt;exceptionally&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ex&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Handled exception: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Recovered value"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}).&lt;/span&gt;&lt;span class="na"&gt;thenAccept&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;println&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;I hope this article gives you a good starting point to explore the &lt;code&gt;CompletableFuture&lt;/code&gt; class further.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Helpful Links:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://concurrencydeepdives.com/guide-completable-future/" rel="noopener noreferrer"&gt;Concurrency Deep Dives: A Guide to CompletableFuture&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/aruva-io-tech/a-comprehensive-introduction-to-asynchronous-programming-in-java-promises-callbacks-and-futures-747ddfaf3c4b" rel="noopener noreferrer"&gt;A Comprehensive Introduction to Asynchronous Programming in Java — Promises, Callbacks, and Futures&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>java</category>
      <category>asynchronous</category>
      <category>backend</category>
    </item>
    <item>
      <title>This Week I Learnt: gRPC &amp; Protobuf</title>
      <dc:creator>Dara Olayebi</dc:creator>
      <pubDate>Mon, 08 Apr 2024 21:43:31 +0000</pubDate>
      <link>https://dev.to/daraolayebi/this-week-i-learnt-grpc-protobuf-31l8</link>
      <guid>https://dev.to/daraolayebi/this-week-i-learnt-grpc-protobuf-31l8</guid>
      <description>&lt;p&gt;After a (very) long hiatus, I'm back with a writing series I'm calling "This Week I Learnt". Just over a year ago, I started a new job and it has been the most exciting and most challenging experience of my career. Exciting because I'm contributing to a product I love with a brilliant team. Challenging because imposter syndrome reared its ugly head and I spent months working to overcome daily feelings of self-doubt. I was also transitioning into a full stack role with a purely frontend engineering background, so that made everything a little more difficult.&lt;/p&gt;

&lt;p&gt;In my first few months, I was learning so much so quickly as I began to work with large, complex systems. I became exposed to system architecture and design concepts as well as advanced software tooling, a lot of which I'd had very little previous practical experience with. This led me to the idea of a writing series - breaking down some of these concepts as frequently as I can in a way that's easy to understand.&lt;/p&gt;

&lt;p&gt;So, here goes the first one!&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;This Week I Learnt&lt;/strong&gt; how gRPC (General Remote Procedure Call) and protocol buffers work.&lt;/p&gt;

&lt;p&gt;To understand gRPC, it helps to first understand what RPC is. A remote procedure call is a type of communication that allows computer programs to execute code on a remote server as if they were local function calls. In slightly simpler terms, RPC allows developers to make function calls on remote machines or services. It is particularly useful for distributed systems where components are spread across multiple nodes or servers. &lt;em&gt;gRPC&lt;/em&gt; is an open-source API implementation of the RPC model. It was built by Google in 2016 and is now widely used by a lot of companies with large systems. It has multiple benefits over the traditional REST/SOAP API approach, one major one being its performance.&lt;/p&gt;

&lt;p&gt;APIs rely on a communication protocol to determine how to send and receive data. A communication protocol in a nutshell is a set of rules that determine how data is sent over the internet and other networks. HTTP, for example, is the most widely used protocol today, used to send data between clients and servers on the web. File Transfer Protocol (FTP) is another example, and is used to transfer files between computers etc. gRPC relies on the HTTP/2 protocol (which is an upgraded version of HTTP). &lt;/p&gt;




&lt;p&gt;&lt;a href="https://media2.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%2Fyuush8i98wjlujgdjy85.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fyuush8i98wjlujgdjy85.jpg" alt=" " width="800" height="401"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Image credit: &lt;a href="https://www.imperva.com/learn/performance/http2/" rel="noopener noreferrer"&gt;Imperva&lt;/a&gt;&lt;/em&gt; &lt;/p&gt;




&lt;p&gt;In addition, APIs also need to follow a specific data format for communication between clients and servers. REST APIs send and receive data as JSON or XML objects. gRPC APIs on the other hand use Protocol Buffers (or protobuf). These are &lt;code&gt;.proto&lt;/code&gt; files containing messages and a service definition that define the methods of the service and each request and response type. Below is a protobuf file example - it defines a UserInfo service that allows consumers to get a user's profile information and update a user's email:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight protobuf"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Specifies the proto version&lt;/span&gt;
&lt;span class="na"&gt;syntax&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"proto3"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


&lt;span class="c1"&gt;// Request and response for fetching a user's profile&lt;/span&gt;
&lt;span class="kd"&gt;message&lt;/span&gt; &lt;span class="nc"&gt;GetUserProfileRequest&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="na"&gt;user_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;message&lt;/span&gt; &lt;span class="nc"&gt;GetUserProfileResponse&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="na"&gt;user_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="na"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;int64&lt;/span&gt; &lt;span class="na"&gt;phone&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="na"&gt;avatar_url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;repeated&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="na"&gt;followers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Request and response for updating a user's email&lt;/span&gt;
&lt;span class="kd"&gt;message&lt;/span&gt; &lt;span class="nc"&gt;UpdateUserEmailRequest&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="na"&gt;user_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="na"&gt;new_email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;message&lt;/span&gt; &lt;span class="nc"&gt;UpdateUserEmailResponse&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// You can also define enums in these files&lt;/span&gt;
    &lt;span class="kd"&gt;enum&lt;/span&gt; &lt;span class="n"&gt;ResponseStatus&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;SUCCESS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="na"&gt;ERROR&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;ResponseStatus&lt;/span&gt; &lt;span class="na"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="c1"&gt;// API service definition which lists the two API methods and their corresponding request and response&lt;/span&gt;
&lt;span class="kd"&gt;service&lt;/span&gt; &lt;span class="n"&gt;UserInfo&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;rpc&lt;/span&gt; &lt;span class="n"&gt;GetUserProfile&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;GetUserProfileRequest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;returns&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;GetUserProfileResponse&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;rpc&lt;/span&gt; &lt;span class="n"&gt;UpdateUserEmail&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;UpdateUserEmailRequest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;returns&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;UpdateUserEmailResponse&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can have several proto files in your codebase, each one containing a different service and message definitions. &lt;/p&gt;

&lt;p&gt;Once proto files have been defined, they need to be compiled to translate them into code that can be understood and used by various programming languages. For example, consuming a REST API in a JavaScript application can be done via the native &lt;code&gt;fetch()&lt;/code&gt; method or some web client library like Axios. In the gRPC world, we need a way for the data structures defined in the proto files to become readable code. This is done by the &lt;a href="https://grpc.io/docs/protoc-installation/" rel="noopener noreferrer"&gt;protobuf compiler&lt;/a&gt; (protoc). It takes in the proto files as its input, and outputs a bunch of stub code made up of classes and objects that represent your service. The compiler supports multiple programming languages (Java, Python, C++ etc), so can generate stub code in the language you will be using to consume the API.&lt;/p&gt;




&lt;p&gt;The image below is a workflow of the processes required to consume a gRPC API:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fclh0yp4ye5m3udvqhm1j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fclh0yp4ye5m3udvqhm1j.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Image credit: &lt;a href="https://www.ionos.co.uk/digitalguide/server/know-how/an-introduction-to-grpc/" rel="noopener noreferrer"&gt;IONOS Digital Guide&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;Once compiling is done, clients can then begin to interact with the API using the methods generated.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Helpful Links:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://grpc.io/docs/what-is-grpc/introduction/" rel="noopener noreferrer"&gt;What is gRPC (original docs)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.linkedin.com/pulse/restful-vs-rpc-comparing-two-distinct-api-approaches-amr-saafan" rel="noopener noreferrer"&gt;Restful vs RPC comparing two-distinct API approaches&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/expedia-group-tech/the-weird-world-of-grpc-tooling-for-node-js-part-1-40a442966876" rel="noopener noreferrer"&gt;The weird world of gRPC tooling for Node.js&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>appwritehack</category>
      <category>codenewbie</category>
      <category>learning</category>
      <category>career</category>
    </item>
    <item>
      <title>A checklist for prioritising web accessibility</title>
      <dc:creator>Dara Olayebi</dc:creator>
      <pubDate>Fri, 09 Sep 2022 18:45:55 +0000</pubDate>
      <link>https://dev.to/daraolayebi/a-checklist-for-prioritising-web-accessibility-ch</link>
      <guid>https://dev.to/daraolayebi/a-checklist-for-prioritising-web-accessibility-ch</guid>
      <description>&lt;p&gt;In the spirit of being transparent, I haven't always prioritised accessibility. This is not to say that I've deliberately built applications to be inaccessible, but rather, that it was often an afterthought - something I needed to "tackle" at the end. Because of this mindset, I didn't spend enough time making sure all parts of the user interface were accessible. Over time, I have realised how important it is to make it a natural part of my development process from the jump.&lt;/p&gt;

&lt;p&gt;In a nutshell, accessibility on the web refers to the ability for &lt;strong&gt;everyone&lt;/strong&gt; to successfully perceive, operate, understand and access a website or web application. People with disabilities use assistive technologies - screen readers, screen magnifiers, Braille displays, voice control, to name a few - to access the web.&lt;/p&gt;




&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft657mhhn4nh6tc5njrx4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft657mhhn4nh6tc5njrx4.png" alt="Categories of differently-abled people" width="800" height="389"&gt;&lt;/a&gt;&lt;/p&gt;
Different categories of disabilities (source: Microsoft's inclusive design kit)






&lt;p&gt;Before diving in, we'll go behind the scenes a little bit. When a browser loads a webpage, a couple of things happen. One of those things is the creation of what is called the &lt;strong&gt;Accessibility Tree&lt;/strong&gt; - the browser takes the DOM tree and transforms it into a version that assistive technologies can understand. The Accessibility Tree consists of the name, role, value and state (along with other properties) of elements on a webpage. Technologies such as screen readers will refer to this tree to relay information to its users.&lt;/p&gt;




&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdwrbmpbdg1qyfmbqdw0n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdwrbmpbdg1qyfmbqdw0n.png" alt="Chrome's Accessibility Tree" width="800" height="560"&gt;&lt;/a&gt;&lt;/p&gt;
Chrome's Accessibility Tree (within Developer tools) showing the accessibility data for a button on the page






&lt;p&gt;To ensure website developers stick to accessibility rules, the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/Accessibility/Understanding_WCAG"&gt;WCAG&lt;/a&gt; (Web Content Accessibility Guidelines) were introduced many years ago. This article highlights some of these guidelines in a checklist format that can be easily followed during the development process.&lt;/p&gt;




&lt;h3&gt;
  
  
  ✔️ Are you using semantic HTML?
&lt;/h3&gt;

&lt;p&gt;By default, &lt;a href="https://motherfuckingwebsite.com/"&gt;HTML is accessible&lt;/a&gt;. However, the more elaborate a website becomes - as is the case nowadays - the greater the need to ensure that it remains accessible. Using semantic HTML sets the foundation.&lt;/p&gt;

&lt;p&gt;Semantic elements (&lt;code&gt;header&lt;/code&gt;, &lt;code&gt;footer&lt;/code&gt;, &lt;code&gt;main&lt;/code&gt;, &lt;code&gt;aside&lt;/code&gt;, &lt;code&gt;article&lt;/code&gt;, &lt;code&gt;button&lt;/code&gt;, &lt;code&gt;nav&lt;/code&gt;, &lt;code&gt;menu&lt;/code&gt; &lt;code&gt;cite&lt;/code&gt;, &lt;code&gt;em&lt;/code&gt;, to name a few) introduce meaning to a webpage which means that assistive technologies are able to establish landmark regions and identify what the layout and sections of the page are.&lt;/p&gt;

&lt;p&gt;As I read somewhere, "developing semantic websites solves more than 50% of the most common accessibility issues."&lt;/p&gt;




&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjl1er992y5m99502e6qq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjl1er992y5m99502e6qq.png" alt="Semantic vs Non-semantic code" width="800" height="430"&gt;&lt;/a&gt;&lt;/p&gt;
Semantic vs Non-semantic code






&lt;p&gt;In some cases, there might be no semantic element in existence for what needs to be achieved - for example, building a dropdown menu - and the alternative would be to create a custom element. This has the potential to affect accessibility which is where ARIA comes in (discussed later on).&lt;/p&gt;

&lt;p&gt;More on semantics: &lt;a href="https://learn-the-web.algonquindesign.ca/topics/html-semantics-cheat-sheet/"&gt;HTML semantics cheat sheet&lt;/a&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  ✔️ Does every element have a name?
&lt;/h3&gt;

&lt;p&gt;Just as people are addressed by name, so are web elements when it comes to accessibility. The name of an element (also called "accessible name") is one of the values that screen readers will announce to users as they navigate a website.&lt;/p&gt;

&lt;p&gt;Elements get their default accessible names from different sources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Image names come from the alt attribute.&lt;/li&gt;
&lt;li&gt;Button names come from the button's text contents (or from the alt value of an enclosing image, if one exists).&lt;/li&gt;
&lt;li&gt;Table names come from the title attribute.&lt;/li&gt;
&lt;li&gt;Form input names come from the placeholder, associated label or title attribute.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here are some examples of three web elements followed by a screenshot of the MacOS screen reader announcement of each element:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"button"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Settings&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvfmai60rmdrz25ndck46.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvfmai60rmdrz25ndck46.png" alt="Screen reader announcement" width="800" height="136"&gt;&lt;/a&gt;&lt;/p&gt;
Screen reader announcement for a button








&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/settings/labels"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Manage Labels&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjxf6n4hx0r5ca9w0kfqb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjxf6n4hx0r5ca9w0kfqb.png" alt="Screen reader announcement" width="800" height="136"&gt;&lt;/a&gt;&lt;/p&gt;
Screen reader announcement for a link








&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;form&lt;/span&gt; &lt;span class="na"&gt;role=&lt;/span&gt;&lt;span class="s"&gt;"search"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"q"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Search:&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"q"&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"q"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fntkfi4og4o9kiwekho8j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fntkfi4og4o9kiwekho8j.png" alt="Screen reader announcement" width="800" height="136"&gt;&lt;/a&gt;&lt;/p&gt;
Screen reader announcement for a form with a search field






&lt;p&gt;Sometimes, an element needs to be explicitly given its accessible name. Here are two example scenarios:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A "Read more" link that requires additional context for visually impaired users&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Icon buttons that have no text&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp1mt8713s8av9dbibo8i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp1mt8713s8av9dbibo8i.png" alt="Icon buttons from Dev's Create Post page" width="800" height="182"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ARIA to the rescue!&lt;/p&gt;

&lt;p&gt;If you scroll up to the screenshot of Chrome's Accessibility Tree at the beginning of the article, you'll notice the section titled "ARIA attributes".&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;ARIA (Accessible Rich Internet Applications) is a set of roles, states and properties that can be added to an element to specify how it should behave.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The &lt;code&gt;aria-label&lt;/code&gt; attribute will override an element's accessible name.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"button"&lt;/span&gt; &lt;span class="na"&gt;aria-label=&lt;/span&gt;&lt;span class="s"&gt;"Shopping Cart"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;svg&amp;gt;&lt;/span&gt;
     ...
  &lt;span class="nt"&gt;&amp;lt;/svg&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;aria-label=&lt;/span&gt;&lt;span class="s"&gt;"Read more about the blog post on global travel"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
   Read more
&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;Key things to note:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;All images should have an &lt;code&gt;alt&lt;/code&gt; attribute. 

&lt;ul&gt;
&lt;li&gt;If the image is purely decorative (e.g. a question mark icon next to a Help button or a magnifying glass icon within a search input), the alt text should be an empty string (this prevents screen readers from announcing a redundant element).&lt;/li&gt;
&lt;li&gt;If the image is not redundant and serves a purpose, the alt text should describe exactly &lt;strong&gt;what the image is&lt;/strong&gt; or in some cases, &lt;strong&gt;what the image does&lt;/strong&gt;. &lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;All HTML form inputs should have an associated descriptive label to enhance accessibility.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So it's pretty obvious that an element with no name could affect a user's experience. Examining the Accessibility Tree to make sure elements have proper naming will increase the amount of context screen readers provide to users.&lt;/p&gt;

&lt;p&gt;More on accessible names: &lt;a href="https://sarahmhigley.com/writing/whats-in-a-name/"&gt;What's in a name?&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  ✔️ Are headings in hierarchical order?
&lt;/h3&gt;

&lt;p&gt;Some assistive technology users prefer to navigate a page using headings, especially on sites that have a lot of content, for example Wikipedia. Headings should have the correct hierarchy (i.e. &lt;code&gt;&amp;lt;h3&amp;gt;&lt;/code&gt; must come before &lt;code&gt;&amp;lt;h4&amp;gt;&lt;/code&gt;) to give users a sense of how the page content is structured. &lt;/p&gt;

&lt;p&gt;Headings should also be as succinct and as descriptive as possible to properly illustrate the content they introduce.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;WCAG says: The heading elements should be organized in descending order without skipping a level, meaning that an h4 should only come after an h3. Skipping heading levels will cause screen reader users to wonder if content is missing.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It can be tempting  to order headings by size and not by level. In such cases, CSS utility classes can be used to make elements appear visually smaller or bigger regardless of their heading level.&lt;/p&gt;

&lt;p&gt;More on headings hierarchy: &lt;a href="https://www.a11yproject.com/posts/how-to-accessible-heading-structure/"&gt;Accessible heading structure&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  ✔️ Does your content have a logical tab order and visible focus indicators?
&lt;/h3&gt;

&lt;p&gt;Not all users make use of a mouse or a trackpad. Some have to rely on the keyboard, while others choose to. Regardless, ensuring that this group of users can successfully navigate a webpage should be a priority.&lt;/p&gt;

&lt;p&gt;HTML elements are either presentational (div, span, section, article) or interactive (a, button, input, select, textarea). By default, interactive elements are focusable. A keyboard user will click the tab key to jump from one focusable element to the next.&lt;/p&gt;

&lt;p&gt;The order in which users tab through the page is based on the order of the DOM, and the order of the DOM is based on the order of the HTML markup. Therefore, it is important to prioritise how you write your code as it will determine how keyboard users navigate your site. For example, if your UI is supposed to display article content to the left and the article heading to the right, your HTML should be written in the normal order with the article heading appearing first and the article content second. CSS can then be used to adjust the visual appearance of the page.&lt;/p&gt;

&lt;p&gt;The page tab order can also be altered using &lt;code&gt;tabindex&lt;/code&gt; - this attribute determines where an element will fall in the tab flow. The default &lt;code&gt;tabindex&lt;/code&gt; value of interactive elements is 0. An element given a value of -1 will be removed from the tab flow, while an element given a value of 1 will take precedence over other elements. The latter should be avoided as it could affect the user's navigation flow on the page.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;tabindex=&lt;/span&gt;&lt;span class="s"&gt;"1"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;I will be focused before all other elements&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;tabindex=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;I am the default&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;tabindex=&lt;/span&gt;&lt;span class="s"&gt;"-1"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;I will never be in focus&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;Key things to note:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Make sure any element that the user needs to interact with, particularly custom controls like a dropdown menu, have a &lt;code&gt;tabindex&lt;/code&gt; value of 0. Otherwise, a keyboard user will never be able to access it.&lt;/li&gt;
&lt;li&gt;If an element is visually hidden but may be interacted with at some point by the user (e.g. a pop-up modal), it should be set to &lt;code&gt;display: none&lt;/code&gt; or &lt;code&gt;visibility: hidden&lt;/code&gt; to prevent focus until it becomes visible.&lt;/li&gt;
&lt;li&gt;If an element is visually hidden and will never involve any interaction from the user, it should be given a &lt;code&gt;tabindex&lt;/code&gt; value of -1 to remove it from the focus flow entirely.&lt;/li&gt;
&lt;li&gt;When used for interactive controls, non-semantic elements are inaccessible via the keyboard (e.g. using a &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; to create a button) and will require some Javascript to be written to be made accessible. Semantic elements on the other hand have built-in keyboard accessibility. &lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;So how does a keyboard user know what element is in focus while they tab through the page?&lt;/p&gt;

&lt;p&gt;As &lt;a href="https://www.sarasoueidan.com/blog/focus-indicators/#:~:text=%20a%20keyboard%20user%E2%80%99s%20cursor%20equivalent%20is%20the%20focus%20indicator."&gt;Sara Soueidan wrote&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A keyboard user’s cursor equivalent is the focus indicator.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Removing the browsers default focus indicator (using &lt;code&gt;outline: none&lt;/code&gt;) without replacing it with another one makes a site inaccessible. Today, in addition to &lt;code&gt;:focus&lt;/code&gt;, most browsers support the &lt;code&gt;:focus-visible&lt;/code&gt; pseudo-class which will be applied when an element is in focus and the user's input is a keyboard.&lt;/p&gt;




&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsct5lqledwl7yfckg7po.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsct5lqledwl7yfckg7po.png" alt="Focus indicator is displayed on the menu item" width="800" height="395"&gt;&lt;/a&gt;&lt;/p&gt;
The focus indicator is displayed on the "Paid Courses" menu item via a keyboard






&lt;p&gt;Here's how to use &lt;code&gt;:focus-visible&lt;/code&gt; from MDN's docs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.button&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="no"&gt;darkgray&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;4px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.button&lt;/span&gt;&lt;span class="nd"&gt;:focus-visible&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c"&gt;/* Draw the focus when :focus-visible is supported */&lt;/span&gt;
  &lt;span class="nl"&gt;outline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="no"&gt;deepskyblue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;outline-offset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;@supports&lt;/span&gt; &lt;span class="n"&gt;not&lt;/span&gt; &lt;span class="n"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;(:&lt;/span&gt;&lt;span class="n"&gt;focus-visible&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;.button.with-fallback&lt;/span&gt;&lt;span class="nd"&gt;:focus&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;/* Fallback for browsers without :focus-visible support */&lt;/span&gt;
    &lt;span class="nl"&gt;outline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="no"&gt;deepskyblue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;outline-offset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;More on focus indicators: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.sarasoueidan.com/blog/focus-indicators/"&gt;A guide to designing accessible, WCAG-compliant focus indicators&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.w3.org/TR/WCAG22/#focus-appearance"&gt;WCAG guidelines on focus indicators&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  ✔️ Are you using ARIA attributes appropriately?
&lt;/h3&gt;

&lt;p&gt;As we saw above, ARIA lets you modify the way an element is presented to assistive technologies. &lt;/p&gt;

&lt;p&gt;You can use ARIA to define the role of an element e.g. &lt;code&gt;role="dialog"&lt;/code&gt;, or set its state e.g. &lt;code&gt;aria-checked="true"&lt;/code&gt;. You can also use it to make custom controls accessible. For example, if you choose to create a checkbox instead of using HTML's native checkbox element, you would need to add ARIA states and properties to make your checkbox usable and accessible. &lt;/p&gt;

&lt;p&gt;As useful as ARIA is however, it is not always required. Semantic markup should always be used where possible.&lt;/p&gt;

&lt;p&gt;More on ARIA: &lt;a href="https://gomakethings.com/when-should-you-use-aria/"&gt;When should you use ARIA&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  ✔️ Are you choosing colours carefully?
&lt;/h3&gt;

&lt;p&gt;Very often, when it comes to colours, I have prioritised aesthetics over accessibility without realising it, neglecting a large group of people in the process.&lt;/p&gt;

&lt;p&gt;With more awareness comes more consideration for users who are blind or have low vision. This means prioritising the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Making sure all text has the right amount of contrast with its background. WCAG expects a website's background to text contrast ratio to be at least &lt;a href="https://www.w3.org/TR/WCAG21/#contrast-minimum:~:text=The%20visual%20presentation%20of%20text%20and%20images%20of%20text%20has%20a%20contrast%20ratio%20of%20at%20least%204.5%3A1"&gt;4.5:1&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftileamacptweqeesfooj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftileamacptweqeesfooj.png" alt="Chrome's colour contrast tool which shows selected colours pass (left) and fail (right) contrast ratio check" width="800" height="492"&gt;&lt;/a&gt;&lt;/p&gt;
Chrome's colour contrast tool which shows selected colours pass (left) and fail (right) contrast ratio check



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Including text alternatives to depict different coloured interactive states. For example, error, success or warning states.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Using focus indicators that have enough contrast with the surrounding element or background.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Although this is unrelated to colour, it's important to also take into account other UI elements like font sizes, line heights and letter spacing, and consider how well content can be perceived on a website.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;More on colour: &lt;a href="https://uxmovement.com/content/why-you-should-never-use-pure-black-for-text-or-backgrounds/"&gt;Here's why you should never use pure black for text or backgrounds&lt;/a&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  ✔️ Are you letting users know when dynamic content changes?
&lt;/h3&gt;

&lt;p&gt;Imagine a visually impaired user sending messages on a website's customer service chat widget but not being made aware whenever they receive a response?&lt;/p&gt;

&lt;p&gt;If you have any time sensitive notifications on your website that are vital to a user's experience, you should explore using &lt;code&gt;aria-live&lt;/code&gt;. This attribute can be added to any element and allows website developers determine how screen readers should notify users about changes on a webpage.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;aria-live="off"&lt;/code&gt;: No announcements will be made ("off" is the default).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;aria-live="polite"&lt;/code&gt;: Announcements will be made only after a user has completed a process i.e. the user will not be interrupted.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;aria-live="assertive"&lt;/code&gt;: The user will be interrupted so the announcement can be made.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Web accessibility is a much broader topic than this article covers. However, as I started to prioritise it in all the ways mentioned above, it led to a major shift in my perspective, motivated me to re-evaluate the way I build user interfaces, and is ultimately making me a more thoughtful developer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Helpful resources:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://aneventapart.com/news/post/practical-tips-for-building-more-accessible-front-ends"&gt;Practical tips for building more accessible front-ends&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.a11yproject.com/"&gt;The A11y Project&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://gomakethings.com/hidden-content-for-better-a11y/"&gt;Hidden content for better a11y&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://a11y-101.com/development/skip-link"&gt;Skip links&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/pa11y/pa11y"&gt;Pa11y - automated accessibility testing tool&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.codehousegroup.com/insight-and-inspiration/tech-stream/google-lighthouse-accessibility"&gt;Google Lighthouse&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>a11y</category>
      <category>webdev</category>
      <category>frontend</category>
      <category>html</category>
    </item>
    <item>
      <title>Everything I learnt building my first DApp - a frontend perspective</title>
      <dc:creator>Dara Olayebi</dc:creator>
      <pubDate>Fri, 08 Apr 2022 15:51:49 +0000</pubDate>
      <link>https://dev.to/daraolayebi/everything-ive-learnt-building-my-first-dapp-a-frontend-perspective-4in4</link>
      <guid>https://dev.to/daraolayebi/everything-ive-learnt-building-my-first-dapp-a-frontend-perspective-4in4</guid>
      <description>&lt;p&gt;&lt;em&gt;This article is a walkthrough of my process and learnings building a DApp using React, WAGMI &amp;amp; ethers.js.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I was recently given a task at work to build the client side of a DApp (decentralised application). I watched a number of tutorials but still had a hard time figuring out why I needed certain libraries / services and more importantly, how to put all the various pieces together. If you’re trying to figure this out too, then keep reading! &lt;/p&gt;

&lt;p&gt;The frontend of a DApp is built very similarly to a traditional web application (using a mix of HTML, CSS &amp;amp; JavaScript), but instead of interacting with a database via an API, you’re interacting directly with the blockchain via a smart contract (a program written to execute a set of instructions). In order to be fully decentralised, DApps are also often hosted on peer-to-peer (P2P) networks instead of centralised hosting servers. Here's a summary:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Traditional web application:&lt;/strong&gt; Client → API → Database&lt;br&gt;
&lt;strong&gt;Decentralised application:&lt;/strong&gt; Client → Smart Contract → Blockchain&lt;/p&gt;

&lt;p&gt;Here's how it went!&lt;/p&gt;


&lt;h2&gt;
  
  
  Setting up the DApp
&lt;/h2&gt;

&lt;p&gt;After initialising a new React project, the first thing I did was to install a package that will enable communication with the blockchain. Two of the most widely-used Javascript libraries for this are &lt;a href="https://web3js.readthedocs.io/"&gt;Web3.js&lt;/a&gt; and &lt;a href="https://docs.ethers.io/v5/"&gt;Ethers.js&lt;/a&gt;. I did some digging to understand how they work under the hood.&lt;/p&gt;

&lt;p&gt;The blockchain is made up of many nodes, each of which stores a copy of the data on the blockchain. To read or write any of this data, my application needed to be able to communicate with one of these nodes. These libraries provide developers with access to various modules (with methods and properties) for interacting with a local or remote Ethereum node. For example:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ethers.Wallet&lt;/code&gt; is used to connect to an Ethereum wallet.&lt;br&gt;
&lt;code&gt;ethers.Contract&lt;/code&gt; is used to interact with a smart contract on the Ethereum blockchain.&lt;/p&gt;

&lt;p&gt;Both libraries will allow you to achieve the same things. However, if you’re unsure about which one to use, &lt;a href="https://blog.infura.io/ethereum-javascript-libraries-web3-js-vs-ethers-js-part-i/"&gt;this article&lt;/a&gt; does a good comparison study. &lt;/p&gt;

&lt;p&gt;I also needed a crypto wallet. A wallet acts as a login / gateway to a DApp. In traditional web applications, users are prompted to sign in with an email address and a password. In the decentralised world, DApps need to be given permission to access a user's wallet in order to enable certain functionality (more on this later). I installed &lt;a href="https://metamask.io/"&gt;Metamask&lt;/a&gt; which is one of the most popular wallet solutions, and is accessible via a &lt;a href="https://chrome.google.com/webstore/detail/metamask/nkbihfbeogaeaoehlefnkodbefgpgknn"&gt;Chrome extension&lt;/a&gt; or a mobile app.&lt;/p&gt;

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

&lt;p&gt;Once I had both ethers.js and Metamask installed, I was good to go.&lt;/p&gt;


&lt;h2&gt;
  
  
  Interacting with the smart contract
&lt;/h2&gt;

&lt;p&gt;I had what I needed to communicate with the blockchain. Next, I needed to figure out how to interact with the "middleman" - the smart contract. &lt;/p&gt;

&lt;p&gt;Connecting to a smart contract requires you to have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The contract address&lt;/li&gt;
&lt;li&gt;The contract ABI&lt;/li&gt;
&lt;li&gt;A provider and/or a signer &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The contract address is the address of the contract on the blockchain. The ABI (Application Binary Interface) is a file that contains a breakdown of each function in the contract along with its input parameters (if any), expected output and data types, in JSON format. Both of these can be found on &lt;a href="https://etherscan.io"&gt;Etherscan&lt;/a&gt;, a blockchain explorer for Ethereum that allows you to view smart contracts (plus much more). &lt;/p&gt;

&lt;p&gt;Providers and signers are essential parts of a DApp. A smart contract can consist of both read and write functions. To read data from a smart contract, you require a provider. To write data (i.e. perform transactions that will change the state of the data on the blockchain), you require a signer. To do both, you require a signer that has a provider.&lt;/p&gt;

&lt;p&gt;A provider provides (pun intended) a link to an Ethereum node that your application will communicate with. There are multiple third party services that offer node providers so you don't have to run your own local node. Some of them are Infura, Metamask (uses Infura under the hood), Quicknode and Alchemy.  &lt;/p&gt;

&lt;p&gt;I got started with &lt;a href="https://infura.io/"&gt;Infura&lt;/a&gt;, created an account and got a Project ID in a few minutes. I was able to create a provider using the built-in Infura provider option on Ethers.js:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const provider = new ethers.providers.InfuraProvider('rinkeby', INFURA_PROJECT_ID);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Signers on the other hand are essentially an abstraction of the user's wallet address. If you are performing any write operation to the blockchain, you will need to sign the transaction (i.e. prove that you are who you are). &lt;/p&gt;

&lt;p&gt;Finally, I created a contract instance that will be used across the application, passing in the contract address, ABI and signer.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const contract = new ethers.Contract(CONTRACT_ADDRESS, CONTRACT_ABI, provider or signer);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this done, I could call any smart contract function like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const result = await contract.functionName();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Handling the wallet connection
&lt;/h2&gt;

&lt;p&gt;The final bit was to figure out how to handle connecting the DApp to a wallet.&lt;/p&gt;

&lt;p&gt;In addition to Metamask, my application was to provide users with two other wallet connector options.&lt;/p&gt;

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

&lt;p&gt;Fortunately, there are several packages that remove the need to write code for each connector separately. I used &lt;a href="https://wagmi.sh/"&gt;WAGMI&lt;/a&gt; which is a React hooks library built on top of ethers.js. WAGMI does a lot more than just handle wallets. It uses over 20 different hooks to abstract a lot of the ethers.js functionality.&lt;/p&gt;

&lt;p&gt;This &lt;a href="https://wagmi.sh/guides/connect-wallet"&gt;guide&lt;/a&gt; on their website explains in detail how to configure wallets. I found it really easy to integrate. Other similar libraries include web3-react and web3-modal. &lt;/p&gt;

&lt;p&gt;One important thing to note: Wallets come with a number of networks you can select from.&lt;/p&gt;

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

&lt;p&gt;There is the main network (Ethereum mainnet) which is for production purposes and multiple test networks (Ethereum testnets) that replicate the Ethereum production environment and are used to develop and test smart contracts. Each testnet has its own properties and supports a specific set of clients.&lt;/p&gt;

&lt;p&gt;It's also important to make sure that your wallet is on the same network your smart contract is deployed on - in my case, Rinkeby - otherwise, requests will fail. I used WAGMI's useNetwork hook to flag when the user is on the wrong network.&lt;/p&gt;




&lt;p&gt;Other things worth mentioning:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;To fund your wallet with test tokens (particularly to test write functions as they incur gas fees), you will need to use a faucet - a website that distributes small amounts of crypto for free in exchange for performing certain actions. I used &lt;a href="https://faucet.rinkeby.io/"&gt;Rinkeby's faucet&lt;/a&gt; and got some test ETH within minutes. However, other options are &lt;a href="https://faucets.chain.link/rinkeby"&gt;Chainlink's faucet&lt;/a&gt; and &lt;a href="https://app.mycrypto.com/faucet"&gt;MyCrypto&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It's extremely important to pass each contract function the correct data in the expected data type. Otherwise, you might end up paying an exorbitant amount in gas fees due to an input error. Thankfully, Metamask warns you when your transaction is likely to fail.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If your application needs to display a list of tokens (with their meta information, current prices etc), I would recommend &lt;a href="https://www.coingecko.com/en/api/documentation"&gt;Coingecko's API&lt;/a&gt; which is what I used.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Helpful resources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://mirror.xyz/dhaiwat.eth/O5CK6Tjfv8uhl6FPbjT0yZ8LUwViDPWGYHdu9khRWpM"&gt;A guide to Web3 for Web2 Frontend Developers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bitsofco.de/calling-smart-contract-functions-using-web3-js-call-vs-send/"&gt;Understanding how to call different smart contract functions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/edatweets_/intro-to-dapps-create-your-dapp-frontend-wreact-38fi"&gt;Create your DApp frontend with React&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/nazeeh21/integrate-your-react-app-with-smart-contracts-4o3m"&gt;Integrate a smart contract into your React app&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Please feel free to reach out if you have any questions, comments or notice any errors.&lt;/p&gt;

&lt;p&gt;Also, here’s to finally publishing my first article! 🥂 &lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>web3</category>
      <category>frontend</category>
    </item>
  </channel>
</rss>
