<?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>Forem: AKQA Leap</title>
    <description>The latest articles on Forem by AKQA Leap (@akqa_leap).</description>
    <link>https://forem.com/akqa_leap</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%2Forganization%2Fprofile_image%2F2343%2F79864bc2-55a7-4f72-a42c-58456a5d2ef2.png</url>
      <title>Forem: AKQA Leap</title>
      <link>https://forem.com/akqa_leap</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/akqa_leap"/>
    <language>en</language>
    <item>
      <title>Using Google Cloud Firestore with Django's ORM</title>
      <dc:creator>Luke Benstead</dc:creator>
      <pubDate>Mon, 20 May 2024 14:34:06 +0000</pubDate>
      <link>https://forem.com/akqa_leap/using-google-cloud-firestore-with-djangos-orm-2fin</link>
      <guid>https://forem.com/akqa_leap/using-google-cloud-firestore-with-djangos-orm-2fin</guid>
      <description>&lt;p&gt;&lt;a href="https://www.djangoproject.com/" rel="noopener noreferrer"&gt;Django&lt;/a&gt; has long been the most popular Python framework for developing web applications. One of its most powerful features is its built in object-relational mapper (ORM) which is designed to flexibly and safely interact with SQL databases in an abstract way.&lt;/p&gt;

&lt;p&gt;A long time ago, a fork of Django called “Django-nonrel” experimented with the idea of using Django’s ORM with a non-relational database; what was then called the App Engine Datastore, but is now known as &lt;a href="https://cloud.google.com/datastore/" rel="noopener noreferrer"&gt;Google Cloud Datastore&lt;/a&gt; (or technically, Google Cloud Firestore in Datastore Mode). Since then a more recent project called "&lt;a href="https://pypi.org/project/django-gcloud-connectors/" rel="noopener noreferrer"&gt;django-gcloud-connectors&lt;/a&gt;" has been developed by &lt;a href="https://p.ota.to/" rel="noopener noreferrer"&gt;Potato&lt;/a&gt; to allow seamless ORM integration with Google Cloud Datastore. &lt;/p&gt;

&lt;p&gt;The intention was always to expand that functionality to other Google hosted no-SQL databases, and today &lt;strong&gt;I’m pleased to announce that &lt;a href="https://pypi.org/project/django-gcloud-connectors/1.2.0/" rel="noopener noreferrer"&gt;django-gcloud-connectors now has support&lt;/a&gt; for &lt;a href="https://cloud.google.com/firestore/" rel="noopener noreferrer"&gt;Google Cloud Firestore in Native Mode&lt;/a&gt;.&lt;/strong&gt; This means you can now build a robust Django-powered website or API driven from a Firestore database which could for example be shared with your Firebase backed mobile application.&lt;/p&gt;

&lt;p&gt;It might seem that using Django’s &lt;strong&gt;relational&lt;/strong&gt; mapper on a &lt;strong&gt;non-relational&lt;/strong&gt; database would be like forcing a square peg into a round hole - but it turns out that the Django ORM works quite elegantly with a non-relational database, and gives you the tools you need to build reusable patterns to get the most out of a massively scalable database.&lt;/p&gt;

&lt;p&gt;Take for example the schemaless nature of a non-rel database like Cloud Datastore which allows each document to have different properties to the other documents in the same table; while powerful, in practice you generally need a schema to write code against and to ensure that your data remains consistent. Django’s model structure allows you to maintain a schema (with validation) that can change over time. You can leverage model signals, field defaults or request middleware to migrate data on the fly, without the need for running potentially slow or disruptive database migrations. You hardly need to worry about the database at all while developing, simply add a new model or field in your code and use it. Django with a non-relational database is great for rapid prototyping.&lt;/p&gt;

&lt;p&gt;There are limitations of course; non-relational databases don’t do complex queries - you can’t perform joins; you can have foreign keys, but you can’t fetch or order across those relations in one database query; you can have many-to-many relationships, but not with Django’s ManyToManyField (you need to use a custom list field instead). You might just find some queries are impossible.&lt;/p&gt;

&lt;p&gt;These limitations mean you have to solve problems in a slightly different way. You’ll find you’ll design your models around the queries you need to make; you’ll sometimes have to pre-calculate things when you save a document to make it possible to quickly query for it later, or perhaps use other services like Big Query or background task processing. &lt;/p&gt;

&lt;p&gt;But you can almost always assume that once your code works, it’ll scale well no matter how much data you throw at it; there’s no risk of running an unindexed query on a million rows, or having to think about database replication or sharding. You can rapidly build a product for a startup and know that things will just ramp up when it hits the big time.&lt;/p&gt;

&lt;p&gt;I highly recommend you give it a try, simply follow the instructions in the &lt;a href="https://gitlab.com/potato-oss/google-cloud/django-gcloud-connectors/" rel="noopener noreferrer"&gt;django-gcloud-connectors repository&lt;/a&gt; and you’ll be up and running in no time. If you’re hosting on Google App Engine you might also be interested in the Djangae project which provides useful utilities and Django apps to integrate with Google Cloud services.&lt;/p&gt;

</description>
      <category>django</category>
      <category>webdev</category>
      <category>googlecloud</category>
      <category>firestore</category>
    </item>
    <item>
      <title>Why accessibility should be a priority, not an afterthought</title>
      <dc:creator>Alexandra Stoica</dc:creator>
      <pubDate>Thu, 20 May 2021 16:07:10 +0000</pubDate>
      <link>https://forem.com/akqa_leap/why-accessibility-should-be-a-priority-not-an-afterthought-3n91</link>
      <guid>https://forem.com/akqa_leap/why-accessibility-should-be-a-priority-not-an-afterthought-3n91</guid>
      <description>&lt;p&gt;We often talk about user-centered design and development, however the process rarely includes accessibility and UX research with users with disabilities or impairments. &lt;a href="https://developer.mozilla.org/en-US/docs/Learn/Accessibility/What_is_accessibility" rel="noopener noreferrer"&gt;(Web) accessibility is the practice of making your websites usable by as many people as possible&lt;/a&gt;, thus providing equal access to information and communications technologies, including the Web, to people with disabilities or impairments. Simply put, accessibility is a &lt;strong&gt;&lt;em&gt;&lt;a href="https://www.un.org/development/desa/disabilities/convention-on-the-rights-of-persons-with-disabilities/article-9-accessibility.html" rel="noopener noreferrer"&gt;basic human right&lt;/a&gt;&lt;/em&gt;&lt;/strong&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  Accessibility is good for all users
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.who.int/en/news-room/fact-sheets/detail/disability-and-health" rel="noopener noreferrer"&gt;Over one billion (or 15% of the population) people live with some form of disability&lt;/a&gt;. Some examples may include auditory, cognitive, neurological, physical, speech, and visual disabilities or impairments. While a disability means that the person finds it difficult to perform everyday tasks to a level that is considered normal for most people, an impairment is medical and represents a condition or symptoms that a person experiences (i.e., low vision). These conditions can be permanent (i.e., I am deaf), temporary (i.e., I have an ear infection), or contextual (i.e., I am on a busy train and do not want to play audio). This &lt;a href="http://www.craigabbott.co.uk/blog/accessibility-is-not-an-edge-case" rel="noopener noreferrer"&gt;hardly makes accessibility an edge case&lt;/a&gt;. Technology has been playing a crucial role in facilitating our day to day tasks, but is this the case for &lt;em&gt;everyone&lt;/em&gt;? &lt;/p&gt;

&lt;p&gt;In this &lt;a href="https://youtu.be/Wb2X9kYEvXc" rel="noopener noreferrer"&gt;TEDxMIT talk&lt;/a&gt;, Judy Brewer describes how we should strive for an accessible future: accessible technology provides unprecedented opportunities for people with disabilities. For example, people with visual impairments can now read the news thanks to the &lt;a href="https://webaim.org/techniques/screenreader/" rel="noopener noreferrer"&gt;screen reader&lt;/a&gt;, and people with speech and motor impairments can use &lt;a href="https://experiments.withgoogle.com/looktospeak" rel="noopener noreferrer"&gt;eye-gaze to speak&lt;/a&gt; with others. &lt;/p&gt;

&lt;p&gt;But it does not stop there, &lt;strong&gt;essential for some and useful for all&lt;/strong&gt;, accessibility supports social inclusion: other groups, such as older people or people in developing countries can greatly benefit from accessible and assistive technology. &lt;a href="https://youtu.be/3f31oufqFSM" rel="noopener noreferrer"&gt;Different situations can hinder the experience of anyone using the web&lt;/a&gt;, such as watching a video in a loud environment without captions, or using the web with a poor Internet connection.&lt;/p&gt;

&lt;h2&gt;
  
  
  Accessibility is good for the business
&lt;/h2&gt;

&lt;p&gt;While the Web offers great potential, implementation matters, otherwise this potential remains unrealised. The World Wide Web Consortium (W3C) have defined &lt;a href="https://www.w3.org/TR/WCAG21/" rel="noopener noreferrer"&gt;a wide range of recommendations for making web content more accessible&lt;/a&gt; based on three conformance levels: A, AA, and AAA (from least to most accessible). Sadly, despite all of this, most &lt;a href="https://webaim.org/projects/million/" rel="noopener noreferrer"&gt;websites still fail to adhere to Web Accessibility Guidelines&lt;/a&gt; (WCAG) as oftentimes in software development, accessibility is an afterthought, treated as a feature, rarely tested for, and not properly considered in the design stages.&lt;/p&gt;

&lt;p&gt;Conversely, inaccessible websites hurt business. For example, &lt;a href="https://webaim.org/blog/web-accessibility-and-seo/" rel="noopener noreferrer"&gt;failure to adhere to WCAG negatively affects SEO&lt;/a&gt; (search engine optimisation), which results in Google Search ranking inaccessible websites lower than more accessible ones. Moreover, accessible and inclusive design thinking can lead to &lt;a href="https://www.w3.org/WAI/business-case/" rel="noopener noreferrer"&gt;numerous business outcomes&lt;/a&gt;, helping digital products be more flexible, address unanticipated problems, and &lt;a href="https://www.fastcompany.com/3060090/how-designing-for-the-disabled-is-giving-google-an-edge" rel="noopener noreferrer"&gt;drive innovation&lt;/a&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  The role we play
&lt;/h2&gt;

&lt;p&gt;Inclusive design and accessibility need to be an integral part of the full product lifecycle. Everyone should know about accessibility. At Potato, we use guilds as a way to educate, encourage, and raise awareness of important aspects of product development and challenge ourselves to do better. In 2019, we established the Accessibility Guild to make accessibility part of our product thinking and culture. As members of the guild, we meet regularly to discuss accessibility topics, organise company-wide talks, learn from each other, watch accessibility-related talks, and audit digital products.&lt;/p&gt;

&lt;p&gt;Whether you are an engineer, a designer, a product manager, or whether you work in technology or not, we all play a role in building a more accessible future. It is by no means an easy task, but fortunately we have many &lt;a href="https://dev.p.ota.to/post/why-accessibility-should-be-a-priority-not-an-afterthought-4fvemfvgd83/#resources" rel="noopener noreferrer"&gt;resources&lt;/a&gt; that can help us get there. You might &lt;a href="https://www.theverge.com/2021/5/4/22417837/instagram-captions-sticker-stories-accessibility" rel="noopener noreferrer"&gt;add captions to your Instagram stories&lt;/a&gt;, or &lt;a href="https://help.twitter.com/en/using-twitter/picture-descriptions" rel="noopener noreferrer"&gt;add alt description to your Twitter images&lt;/a&gt;, so next time you make a mark on the World Wide Web, I encourage you to simply ask yourself: &lt;em&gt;is this accessible&lt;/em&gt;? &lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://globalaccessibilityawarenessday.org/" rel="noopener noreferrer"&gt;GAAD&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.w3.org/standards/webdesign/accessibility" rel="noopener noreferrer"&gt;Accessibility - W3C&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Learn/Accessibility/What_is_accessibility" rel="noopener noreferrer"&gt;What is accessibility? - MDN&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.a11yproject.com/" rel="noopener noreferrer"&gt;The A11Y Project&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href="https://webaim.org" rel="noopener noreferrer"&gt;WebAIM: Web Accessibility In Mind&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.w3.org/WAI/standards-guidelines/wcag/" rel="noopener noreferrer"&gt;Web Content Accessibility Guidelines (WCAG) Overview | Web Accessibility Initiative (WAI) | W3C&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.w3.org/WAI/business-case/" rel="noopener noreferrer"&gt;The Business Case for Digital Accessibility | Web Accessibility Initiative (WAI) | W3C&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://webaim.org/blog/web-accessibility-and-seo/" rel="noopener noreferrer"&gt;Web Accessibility and SEO&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://inclusivedesignprinciples.org/" rel="noopener noreferrer"&gt;Inclusive Design Principles&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.fastcompany.com/3060090/how-designing-for-the-disabled-is-giving-google-an-edge" rel="noopener noreferrer"&gt;How Designing For Disabled People Is Giving Google An Edge&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.p.ota.to/post/how-i-learnt-about-accessibility-as-a-junior-developer-48umfv4xp6q/" rel="noopener noreferrer"&gt;How I learnt about accessibility as a junior developer&lt;/a&gt;&lt;/p&gt;

</description>
      <category>gaad</category>
      <category>inclusivedesign</category>
      <category>accessibilityguild</category>
      <category>a11y</category>
    </item>
    <item>
      <title>How the Web works.</title>
      <dc:creator>Matte</dc:creator>
      <pubDate>Fri, 29 Jan 2021 11:59:20 +0000</pubDate>
      <link>https://forem.com/akqa_leap/how-the-web-works-if3</link>
      <guid>https://forem.com/akqa_leap/how-the-web-works-if3</guid>
      <description>&lt;p&gt;If you're starting out in web development or are a bit rusty about the general scaffolding and technologies required to make the web possible, this high level overview could help you avoid time-consuming setbacks. Knowing how the web works enables developers to make informed architectural decisions, pinpoint bottlenecks and errors, and build solutions that are optimised for the medium they're intended for. My intention is to provide enough clarity on the topic without delivering overwhelming details. So let’s begin. Firstly, we’ll set out to define some core concepts, then run through some key processes and technologies. Finally, we’ll wrap up with how these technologies and processes are used to execute the loading of a web page.&lt;/p&gt;

&lt;h3&gt;
  
  
  Networks
&lt;/h3&gt;

&lt;p&gt;Devices can be connected through a wireless medium such as Wi-Fi or a physical medium such as ethernet cable. Two or more connected devices are considered a Network. When connected these devices can communicate with one another. Wirelessly and physically connected devices can be a part of the same network. This is the founding principle of the Internet. The Internet is a network, a global one.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Internet
&lt;/h3&gt;

&lt;p&gt;This global network connects millions of computers, each able to communicate with one another. This connection allows us to email, share files, transfer data, play games, stream films and access the World Wide Web. An Internet service provider (ISP) is an organisation that provides services for accessing and using the Internet.&lt;/p&gt;

&lt;h3&gt;
  
  
  The World Wide Web
&lt;/h3&gt;

&lt;p&gt;Although commonly used interchangeably The World Wide Web, or simply the Web, isn’t the same as the Internet. To help articulate this difference, think of the internet as the roads that connect towns and cities together. The world wide web contains the things you see on the roads like houses and shops. The vehicles are the data moving around - some go between websites and others will be transferring your emails or files across the internet, separately from the web. Another way to look at this difference is; the Internet is infrastructure while the Web is the service on top of that infrastructure. As such, the Internet makes the Web possible but the two are not the same.&lt;/p&gt;

&lt;p&gt;There are some underlying differences in the technologies and processes used between services such as email, streaming and browsing the Web. However this is beyond the scope of this article where we’re focusing on the Web.&lt;/p&gt;

&lt;h3&gt;
  
  
  Clients and Servers
&lt;/h3&gt;

&lt;p&gt;When using the Web we rely on a client-server relationship. Clients, such as web browsers, request and receive information from servers. Servers, on the other hand, receive requests and deliver responses to clients. Requests and responses are dispatched in the form of HTTP messages.&lt;/p&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.p.ota.to%2Fimages%2F5739956077068288%2F" 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.p.ota.to%2Fimages%2F5739956077068288%2F" alt="Laptop as a client  communicating with a server diagram" width="526" height="204"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;A client, in this instance a laptop, and a server demonstrating the request/response communication relationship.&lt;/em&gt;&lt;/p&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.p.ota.to%2Fimages%2F5710150413320192%2F" 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.p.ota.to%2Fimages%2F5710150413320192%2F" alt="Server as a client communicating with a server diagram" width="526" height="204"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;A client is not always the device the user interacts with. A server can also be a client as shown here.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  HTTP/HTTPS
&lt;/h3&gt;

&lt;p&gt;Hypertext Transfer Protocol is the protocol used between clients and servers to communicate. Assets such as images, text, documents, video and audio can all be transferred through HTTP messages. &lt;/p&gt;

&lt;p&gt;Remember our response and request messages? These are the two types of HTTP messages. Both are composed of the following components: a start-line, some headers, an empty line and finally an optional body component. See MDN for &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Messages" rel="noopener noreferrer"&gt;the specifics of an HTTP request&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The S in HTTPS indicates a greater level of security and requires an SSL certificate to use. These certificates ensure transferred data is encrypted making it harder for intermediary parties to read the contents of the messages passed between servers and clients. In other words, this layer of security helps to ensure data (including confidential or sensitive information) remains undisclosed for everyone but its intended recipient.&lt;/p&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.p.ota.to%2Fimages%2F5647975057457152%2F" 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.p.ota.to%2Fimages%2F5647975057457152%2F" alt="Browser URL bar showing padlock icon" width="488" height="216"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;SSL in action. Note the padlock icon to the left of the URL. This indicates the use of HTTPS and so we can have greater confidence that our security is protected.&lt;/em&gt;&lt;/p&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.p.ota.to%2Fimages%2F5681150794137600%2F" 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.p.ota.to%2Fimages%2F5681150794137600%2F" alt="Padlock dropdown example" width="662" height="445"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;You can also click on the padlock icon to show relevant information.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  TCP/IP
&lt;/h3&gt;

&lt;p&gt;Transmission Control Protocol (TCP) is responsible for ensuring data requested through HTTP gets to you in one piece as quickly as possible. It does this in a few key ways:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Firstly, it divides data into packets.&lt;/li&gt;
&lt;li&gt;It then transports these packets individually taking steps to mitigate risk of delay or delivery failure. Such risks include network congestion, unpredictable network behaviour and network traffic, that is, the amount of data moving across a network at a given point in time.&lt;/li&gt;
&lt;li&gt;Finally, it reassembles these packets ensuring all data is accounted for and in the correct order.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Internet Protocol (IP), amongst other things, provides an address system known as IP addresses. All internet connected devices have a unique IP address which takes the following format: 000.000.000.000. The most recent version of IP addresses, IPv6, exists for the purposes of relieving a projected shortage of IP addresses which have the following format: 0000:0000:0000:0000:0000:0000:0000:0000. You can find your IP address by searching for “What is my IP” in your browser. These addresses are used to ensure data is delivered to the correct host. Essentially TCP/IP is how and where data gets delivered.&lt;/p&gt;

&lt;h3&gt;
  
  
  DNS
&lt;/h3&gt;

&lt;p&gt;A Domain Name Server can be thought of as a huge address book and is typically provided by domain name registrars. Typing a domain name into a web browser’s address bar triggers a request to a DNS server. The DNS server communicates with a hierarchical chain of independent, task specific DNS servers until the IP address of the requested domain is found. This IP address is then returned as a response to the client. The client can then request the resources it needs to load a web page from said IP address. DNS servers fall into one of four categories: Recursive resolvers, root nameservers, TLD nameservers and authoritative nameservers.&lt;/p&gt;

&lt;p&gt;Let’s look at the DNS system in a step-by-step narrative. A resolver sits between the client and the remaining nameservers (root, TLD and authoritative), it receives requests in the form of domain names from the client.&lt;/p&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.p.ota.to%2Fimages%2F5673742378205184%2F" 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.p.ota.to%2Fimages%2F5673742378205184%2F" alt="Diagram showing communication relationship between client and servers during domain name lookup" width="518" height="681"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Having received a request, the resolver sends domain information onto the root nameserver in the form of a request of its own. A response from the root nameserver directs the resolver to the TLD nameserver. TLD nameservers contain information specific to a domain extension, be it .com, .co.uk, .org, etc. &lt;/p&gt;

&lt;p&gt;The resolver, now knowing which TLD nameserver to communicate with sends a request to said server. A response directs the resolver to the authoritative nameserver. Sending a request to the authoritative nameserver is resolved in a response containing an IP address. At this point the resolver has communicated with each of the DNS server types and has obtained all the information it needs. &lt;/p&gt;

&lt;p&gt;The resolver then caches the data to speed up future requests to the same domain and responds to the client with the obtained IP address. The client, having obtained the IP address, now knows where to request domain specific resources from in order to render a webpage.&lt;/p&gt;

&lt;p&gt;Throughout this process there’s a consistent pattern of whittling down where to look in an effort to locate the resources the client needs to render a webpage. In brief this takes the form of going from domain name, to the domains extension type (.com, .net, .org) to specific IP.&lt;/p&gt;

&lt;h3&gt;
  
  
  URL
&lt;/h3&gt;

&lt;p&gt;IP addresses aren’t particularly easy to recall from memory. This is where URLs come in. A URL is a human readable address for locating resources needed to render a site.&lt;/p&gt;

&lt;p&gt;A URL is constructed of different parts, each serving a purpose. Let’s take a URL and break it down into its individual parts.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;http://www.example.com:80/path/to/myfile.html?key1=value1&amp;amp;key2=value2#SomewhereInTheDocument&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Protocol (&lt;code&gt;http&lt;/code&gt;):&lt;/strong&gt;&lt;br&gt;
This sets the protocol in which data is transferred across the Web.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Host (&lt;code&gt;www.example.com&lt;/code&gt;):&lt;/strong&gt;&lt;br&gt;
This is what is used alongside DNS lookup to find the IP address of the server that contains our resources.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Port Number (&lt;code&gt;80&lt;/code&gt;):&lt;/strong&gt; These are sometimes seen in URLs. By default, HTTP uses port 80 and HTTPS uses port 443, but a URL like &lt;code&gt;http://www.example.com:8080/path/&lt;/code&gt; specifies that the web browser should connect to the HTTP server running on port 8080 of the target machine.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Path (&lt;code&gt;/path/to/myfile.html&lt;/code&gt;):&lt;/strong&gt; This is the path to the required resource on the server.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Query String (&lt;code&gt;?key1=value1&amp;amp;key2=value2&lt;/code&gt;):&lt;/strong&gt; Query String parameters are a list of key/value pairs separated with the &amp;amp; symbol. Values are optional.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fragment (&lt;code&gt;#SomewhereInTheDocument&lt;/code&gt; ):&lt;/strong&gt; A fragment links to part of the resource itself. On an HTML document, for example, the browser will scroll to the point where the fragment is defined.&lt;/p&gt;

&lt;h3&gt;
  
  
  Loading a web page
&lt;/h3&gt;

&lt;p&gt;Now we know the processes involved in obtaining an IP address let's look at how a client goes about rendering a page. Our client, having received the appropriate IP address from a DNS lookup, can request resources from the server specific to the submitted domain name. The server's initial response contains the pages HTML. The parsing of this HTML by the browser includes sending additional HTTP requests for any resources the file references. Typically this will include Javascript and CSS but can also include images, fonts, audio and many other asset types.&lt;/p&gt;

&lt;p&gt;Having acquired the assets it needs, the browser runs through a series of processes. Firstly the HTML is transformed into a Document Object Model (DOM). The CSS is then transformed into a CSS Object Model (CSSOM). These two models are then combined to form the Render Tree. &lt;/p&gt;

&lt;p&gt;The browser then uses the information from the Render Tree to perform layout and painting of the elements which make up the page. The Layout operation is concerned with calculating the size and location of each element. The Paint operation is concerned with creating layers for the visible properties of each element such as border, background color, gradient, shadow etc. The final step in the process is the Compositing operation where the browser begins to render to the screen. It’s worth noting that these steps can occur after the initial page render as well. For example, the Paint step would be required during resize and animation events too.&lt;/p&gt;

&lt;p&gt;This sequence is known as the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/Performance/Critical_rendering_path" rel="noopener noreferrer"&gt;Critical Rendering Path&lt;/a&gt;, something worth getting familiar with. It helps developers pinpoint performance bottlenecks and to reduce heavy rendering tasks that would affect a users experience.&lt;/p&gt;

&lt;p&gt;For further reading on these processes I recommend this article on &lt;a href="https://medium.com/jspoint/how-the-browser-renders-a-web-page-dom-cssom-and-rendering-df10531c9969" rel="noopener noreferrer"&gt;how the browser renders a web page&lt;/a&gt;. Google provides resources that cover performance, here’s their overview page titled &lt;a href="https://developers.google.com/web/fundamentals/performance/critical-rendering-path" rel="noopener noreferrer"&gt;critical rendering path&lt;/a&gt;. It covers a broader base and makes note of key things to avoid such as render-blocking CSS.&lt;/p&gt;

&lt;h3&gt;
  
  
  In Summary
&lt;/h3&gt;

&lt;p&gt;We’ve covered a huge chunk of the processes and technologies involved in making the web work. From submitting a URL through to the page being rendered on your device. This article is intended to be a succinct overview of the ecosystem as a whole, as such, potentially overwhelming details have been deliberately omitted. Don’t let that stop you from taking what you now know and conducting your own further research. I hope you’ve found this useful, if anything you’re better prepared for making informed architecture decisions and understanding where bottlenecks or errors may be happening. At the very least you’re now equipped to effectively answer the common “What happens when you submit a URL?” interview question!&lt;/p&gt;

</description>
      <category>web</category>
      <category>programming</category>
      <category>internet</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Validation of the tech roundup providing statistics for Android Developers</title>
      <dc:creator>agata</dc:creator>
      <pubDate>Tue, 24 Nov 2020 12:18:53 +0000</pubDate>
      <link>https://forem.com/akqa_leap/validation-of-the-tech-roundup-providing-statistics-for-android-developers-1e6e</link>
      <guid>https://forem.com/akqa_leap/validation-of-the-tech-roundup-providing-statistics-for-android-developers-1e6e</guid>
      <description>&lt;p&gt;We're reaching out to Android Developers who would like to share their thoughts and help us validate the user journey of the tech roundup providing statistics for Android developers across the world. &lt;/p&gt;

&lt;p&gt;Please comment or email &lt;a href="mailto:agata.stasiuk@potatolondon.com"&gt;agata.stasiuk@potatolondon.com&lt;/a&gt; if you'd like to help. &lt;/p&gt;

</description>
      <category>android</category>
      <category>androidstudio</category>
      <category>developer</category>
      <category>research</category>
    </item>
    <item>
      <title>One Engineer's Journey with Mental Health</title>
      <dc:creator>Michael Strutt</dc:creator>
      <pubDate>Mon, 19 Oct 2020 16:30:22 +0000</pubDate>
      <link>https://forem.com/akqa_leap/one-engineer-s-journey-with-mental-health-17lh</link>
      <guid>https://forem.com/akqa_leap/one-engineer-s-journey-with-mental-health-17lh</guid>
      <description>&lt;p&gt;My name is Michael Strutt and I have &lt;a href="https://www.nhs.uk/conditions/generalised-anxiety-disorder/" rel="noopener noreferrer"&gt;Generalised Anxiety Disorder (GAD)&lt;/a&gt;. I was first diagnosed in my early teens, and it has impacted my life to a greater or lesser extent at different times since then. As of January this year I have been having weekly sessions with a Therapist. In light of World Mental Health Day and the increasing spotlight that mental health has seen this year, I would like to share my story, as both a person and an Engineer.&lt;/p&gt;

&lt;p&gt;I’m going to start with some personal history, both because I’m telling my story here and because I think it adds good context. If you want, you can skip to the part where I start talking about the industry as a whole. Or if you’re only interested in what I’m doing to manage things now, that’s cool too. For the rest of you, this is my story: &lt;/p&gt;

&lt;h2&gt;
  
  
  Getting in to coding
&lt;/h2&gt;

&lt;p&gt;I got into building websites quite early on in life. I discovered it right at the start of high school and just got the bug. When I started out it was a great creative outlet for me, building something and seeing the results instantly. It was also a very interesting way for me to connect to the world in a way I had never experienced before. An early site I built offered solutions to common beginner problems with &lt;a href="https://ubuntu.com/" rel="noopener noreferrer"&gt;Ubuntu Linux&lt;/a&gt;. I was amazed that I could put a tutorial or the solution to a problem out there, and it would help a person I had never met living on the other side of the planet.&lt;/p&gt;

&lt;p&gt;As I got older I started to notice the way that I felt when I coded. I could get absorbed in a way that I never found with books. I could really focus my mind on a task without it wandering. I could solve a problem and challenge myself to learn and become better. I felt calmer, accomplished and motivated. I didn’t feel the anxiety so much when I was writing code. It offered me an escape (and in a far more productive way than that time at University when I lost the best part of a month to &lt;a href="https://elderscrolls.bethesda.net/en/oblivion" rel="noopener noreferrer"&gt;The Elder Scrolls: Oblivion&lt;/a&gt;). Although I didn’t learn this until later in life, I was dealing with anxiety by engaging the logic centers of my brain in order to think more rationally and feel better. A technique often taught in &lt;a href="https://www.nhs.uk/conditions/cognitive-behavioural-therapy-cbt/" rel="noopener noreferrer"&gt;Cognitive Behavioural Therapy (CBT)&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In this post I’m going to talk a lot about some of the things that have impacted my mental health in a negative way, but I want to stress at the start that coding has had an overall incredibly positive effect for me. Some of my happiest times professionally have been when I’ve been getting stuck in and coding all day on some really challenging problems. It has continued to be a creative outlet for me. I love the satisfaction and instant gratification of typing a few lines of code and hitting refresh in the browser to see the results. The sense of accomplishment I felt when after a full day of planning and writing out about a page of trigonometry on a notepad, I finally cracked the equation of how to center an item on the page while it was adjusted to have a shrinking 3D perspective. Please try to keep this in mind as you read on.&lt;/p&gt;

&lt;h2&gt;
  
  
  Starting a career as an Engineer
&lt;/h2&gt;

&lt;p&gt;I was in a very fortunate situation after high school. Sixth Form was an obvious choice, my parents were there to support me, and the offer I received from my first choice of University was well below the grades I was predicted to achieve. I studied Computer Science, I wanted to specialise into Web Development, but my Dad advised me to keep my options open. On my course, we were highly encouraged to do a year in industry, and again I was fortunate enough to land my first pick of positions. My outlook was really positive. I had found this thing that I loved, that I had an aptitude for, and that now somebody was prepared to pay me a salary to do. It was my dream scenario.&lt;/p&gt;

&lt;p&gt;There was an amazing honeymoon period on that first job. I was learning every day, keeping my brain active and engaged, stretching my comfort zones by doing new things. I was very smug to be exceeding the expectations that they had for an intern and receive all of the praise that went with it. I very quickly believed that things would be like this forever. That I would continue to soar and be praised and that everyone who told me they saw me doing great things in x years time was right. I mapped out a highly ambitious (although I didn’t &lt;em&gt;think&lt;/em&gt; that it was at the time) trajectory for myself in my head. This came back to bite me later.&lt;/p&gt;

&lt;h2&gt;
  
  
  Early career progression
&lt;/h2&gt;

&lt;p&gt;Everyone goes through life at their own pace, and each and every one of those paces are completely fine. I write this, and logically I know that it is true, but I still struggle to fully believe it. Career progression is a big area of comparison in the industry.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Caveat: this section is written from memories that have almost certainly been recalled through a lens that favours me. I’ve tried to remove the bias towards myself as much as possible, but I’m sure there will still be some left&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I’ve always been "the smart one" in my friend group growing up and at school. That experience translated into expectations of success in the workplace. I was moving from the small town to the big city where I would be recognised with titles and of course money. In my internship I was flying high on the praise of outperforming my position and people seeing great things for me. I had really high expectations of myself.&lt;/p&gt;

&lt;p&gt;I don’t want this to sound like I’m just nursing my ego here, and I’m certainly not complaining about the very comfortable start that I had in life. I am fully aware of just how fortunate I am to have two loving and supportive parents who nurtured my abilities and provided me with a safety net to fall back on when I needed it. I know all of this. What I’m trying to say is that the reality of the situation was a really hard pill to swallow for me.&lt;/p&gt;

&lt;p&gt;I progressed from intern to junior very quickly. I secured a job for when I graduated at the end of my internship, and they even agreed to pay me a retainer salary during my studies. I expected this trajectory to continue up, but it slowed and for a while felt like it had stopped. I stayed in that role for nearly 2 years. I became increasingly frustrated at the lack of progression, at the lack of pay increase. I watched coursemates soar and become indispensable at their startup, cashing in vast stock options at IPO or jet-setting around the world to open new offices for the company.&lt;/p&gt;

&lt;p&gt;Meanwhile I was taking on more responsibilities, learning new frameworks and practicing new ways of working.  I got to the point as a Junior Engineer where I was the unofficial manager of our intern, doing check-ins and goal setting with them, and I was front-end lead on a project for a high-profile project that had 2 seniors on the team. Rather than seeing these things for the achievements that they were, and the foundation of valuable skills that got me to where I am today, all I focused on was how I wasn’t being financially compensated for this increase in ability and responsibility, and how I wasn’t being recognised with a change in title. Why should I put in all this work when I’m being paid half as much as the people I’m teaching? Don’t get me wrong, these things are important. Everyone deserves to be fairly compensated for the work they put in. But for a time it was the be-all and end-all of my career (and, to and extent, life) satisfaction.&lt;/p&gt;

&lt;p&gt;These 2 years had a big impact on my mental health, and in the year that followed I reached probably the lowest point that I’ve ever felt for such a period of time. I had a panic attack while out in public. Thankfully it only happened once, I’d always been able to hide them away before, but the fear of it happening again was debilitating. I was so anxious about it that I was quite literally hiding from social interaction with friends. I became very insular. I moved back in with my parents for a while (for various reasons), and tried out a course of medication that I &lt;em&gt;really&lt;/em&gt; didn’t get on with. I felt defeated. I thought that there was no escape, and in my mind, resigned myself to feeling like this forever.&lt;/p&gt;

&lt;h2&gt;
  
  
  The strain of the work
&lt;/h2&gt;

&lt;p&gt;The work is very mentally challenging, that’s part of what made it appeal to me, a new problem to solve every day. But at times, this gives way to some very negative feelings. How do you deal with finding a problem that you don’t seem to be able to solve? Why does everyone around me seem to be solving problems faster than me? Is this code good enough? What will the other people on my team say when I put this up for review? I’m not going to dive into imposter syndrome. It’s something that a lot of engineers have experienced at some point or another in their career, and there is already some &lt;a href="https://davidwalsh.name/impostor-syndrome" rel="noopener noreferrer"&gt;very well written content&lt;/a&gt; out there that I would encourage you to read.&lt;/p&gt;

&lt;h3&gt;
  
  
  Further comparisons
&lt;/h3&gt;

&lt;p&gt;We all know we shouldn’t compare ourselves to others. I have a quote pinned to the notice board in my bedroom that reads "the only person I am competing with, is the person I was yesterday". It’s a lovely sentiment, and one I try to keep in mind, but it’s very easy to forget in a career that seems to be set up for comparison and competition. As part of the job, you spend a lot of time looking at other people’s code. Whether it’s a code review for one of your colleagues, diving into the inner workings of a library you’re using, or simply looking for answers on StackOverflow, it will take up a significant portion of your time.&lt;/p&gt;

&lt;p&gt;You end up seeing a lot of code that is better than yours. It can be hard to remember that this isn’t because you are objectively worse at coding than the other person. But it’s because this is what that person chose to focus on. They may have learned an entirely different set of things to you that lead them to this place, or may even have had vast amounts of help with it. You also don’t see the struggles that they went through to write this code. You only see the end results. This can be an awesome opportunity to benefit and learn from all the hard work someone else went through to get to the best result, or it can highlight to you just how much you &lt;em&gt;don’t&lt;/em&gt; know. It took me quite a while to shift my mindset to the former, sometimes it’s still a bit of both.&lt;/p&gt;

&lt;p&gt;Code review is a very common best practice for the industry. Most places have it as an integral part of their workflow. When I was introduced to it I found it really tough to begin with. It felt like I was pouring my heart and soul into my work and offering it up to be shot down and torn apart. This couldn’t be further from the truth. Ultimately the goal is for the best code possible to be in a project, for issues to be spotted and addressed before they make it live, and to raise the overall standard of the team. It took me longer than I would like to admit to see it this way. It was only when I stopped having my code reviewed that I realised I missed it. I wasn’t learning as fast anymore. I actively went and sought out other reviewers and ended up getting mentored by the Technical Architect at the time who didn’t even write the same language as me, but made the time for me all the same (the first of many thanks in this article goes to him). After this it became a requirement for me in all future roles, to be able to surround myself with people who knew more than I did about something so that I could learn it from them. Since then I always try to put the same effort into code reviews that I received back then, and will always take the time to explain something fully to someone who is keen to learn.&lt;/p&gt;

&lt;h3&gt;
  
  
  Stresses of the job
&lt;/h3&gt;

&lt;p&gt;There can be a lot of time-related pressures in software engineering. Deadlines might be looming, sometimes moving closer. It can be very difficult to account for every possible thing that needs to be done to build a finished product. You can run into issues or constraints that suddenly add more to your workload, or the simplest of tasks on the surface could end up taking the longest amount of time due to hidden complexity. It can be very hard to explain all of this to someone who ultimately doesn’t &lt;em&gt;really&lt;/em&gt; understand what it is you are doing, yet gets to have the final say in budget and timeline. It’s been this way in the industry for years. My Dad would laugh at some of my stories from my first job because of how familiar they sounded to his experiences 30 years before me.&lt;/p&gt;

&lt;p&gt;I have on rare occasions done some crazy hours to get a project finished for the agreed launch timeline. I have started working on a launch blocker after dinner at the office, and pushed through until I had to catch the last tube home. I was then back in the office the next morning for a successful 8am launch. I’m completely okay with this. In fact I’m proud of it. But this is very much the exception and not the rule. For some this is not the case, and even for me there was a time (with a past employer) when it felt like the only reward for finishing ahead of schedule was starting the next project early, but if the timelines ever slipped it was the team’s responsibility to get things back on track by whatever means necessary.&lt;/p&gt;

&lt;p&gt;There are a lot of things that are changing in favour of team health and reducing these kinds of pressures. From the processes we use to run projects, to the way we try to sell a team with an objective for a period of time rather than a fixed scope of delivery. Even big companies are &lt;a href="https://www.halowaypoint.com/en-us/news/halo-infinite-development-update" rel="noopener noreferrer"&gt;moving the launch date of huge game releases&lt;/a&gt; to make sure things are done properly without putting the team through hell.&lt;/p&gt;

&lt;p&gt;I know that I am very fortunate not to have experienced the worst of these stresses myself. I’ve heard horror stories from others in the industry (some I’ve known, some from around the world) that are far worse than anything I’ve experienced, and I count myself lucky to have had people around me a lot of the way who would fight my corner and make my well-being a priority. But even with all of this there have been times when the pressure has taken its toll on me, where I’ve felt completely overwhelmed by everything I have been juggling, and when the stress I have been feeling has resulted in some serious burn-out and even pretty serious illness.&lt;/p&gt;

&lt;p&gt;This past Christmas, I was burning the candle at both ends pretty hard, feeling the added pressure of a new role and some pretty big shoes to fill. I was so burned out when I finally stopped and took some time off, that it was only then that my body was able to recover enough to start fighting a virus I had picked up, and I was ill for a full month. It was a real wake-up call to start making my well-being more of a priority than I had been. Also, a big thank you to the Coach at Potato who helped me slow down when I was in danger of doing this the year before when I got stressed out about all the complications in my house purchase. She made time in her busy day just to sit and listen to me and allowed me to get things off my chest and just take some time to breathe.&lt;/p&gt;

&lt;h3&gt;
  
  
  The mental load
&lt;/h3&gt;

&lt;p&gt;Being an Engineer can both help and hinder my mind. In the same way that a really complex problem at work can be a really great thing to occupy your mind, it can also be really hard to let go. When the work you are doing is physically in the office, it’s easy to leave it behind. When the work that you are doing is happening in your mind, it’s very hard to leave &lt;em&gt;that&lt;/em&gt; behind (something that has been exacerbated by lockdown). I have had many nights where I was laying awake problem solving, either consciously or subconsciously sifting through the details and trying to find a better way. I’ve even woken up in the night with a sudden realisation of how to re-architect something and been scrambling for pen and paper to write it down before it fades away. If this is something that happens to you, I strongly recommend keeping a pen and paper on your bedside table so you can get these things out of your head.&lt;/p&gt;

&lt;p&gt;I very recently put a lot of work into trying to fix my sleep by following the advice of &lt;a href="https://www.sleepio.com/" rel="noopener noreferrer"&gt;Sleepio&lt;/a&gt;. If you’re having trouble sleeping and are willing to make some serious adjustments to your lifestyle to improve it, then I would highly recommend their course.&lt;/p&gt;

&lt;h2&gt;
  
  
  Opportunities for growth
&lt;/h2&gt;

&lt;p&gt;I don’t want this post to be all doom and gloom. I have a huge amount to be thankful for about my career and the industry I have chosen to work in, I really can’t see myself working in any other. There are a &lt;em&gt;lot&lt;/em&gt; of upsides to it.&lt;/p&gt;

&lt;p&gt;Tech industry jobs generally offer a greater degree of flexibility than jobs in other fields. You get some companies with amazing benefits packages that these days often include support for your well-being and mental health. Being entirely cloud-based and working on laptops has been extremely useful for &lt;a href="https://dev.p.ota.to/post/how-potato-code-remotely-4q64vuq2wb5/" rel="noopener noreferrer"&gt;being able to work from anywhere in the world&lt;/a&gt; too. Something that has been especially useful this year.&lt;/p&gt;

&lt;p&gt;There are also a lot of opportunities to move outside of your comfort zone. Early on in my career, I challenged myself to slowly increase my confidence in being more client facing and took the opportunity to learn how to participate in, then lead, technical interviews.&lt;/p&gt;

&lt;p&gt;I can’t say for sure how typical this is of the industry for lack of personal experience, but working at Potato really helped to normalise the idea of mental health for me. A couple of my colleagues were very open in talking about the fact that they had been to therapy at some point in their life. In the time I have been here, I’ve listened to 4 lightning talks from people about their experiences in topics such as therapy, mindfulness, meditation and personal stories with mental health. It was really eye opening for me that people talked about these things as if they were normal, because they &lt;em&gt;are&lt;/em&gt; normal. I don’t know how much longer it would have taken me to ask for help without this experience normalising the idea for me.&lt;/p&gt;

&lt;p&gt;A big thank you to everyone at Potato who helped change my perspective on therapy and personal development. In particular my former manager, Adam, who challenged me to confront my professional fears as well as sharing his own experiences. He also recommended to me a book that I’ve bought about 5 copies of for friends and colleagues over the past year: &lt;a href="https://www.amazon.co.uk/Feel-Fear-Anyway-Quick-Reads/dp/1785041126/" rel="noopener noreferrer"&gt;Feel the Fear and Do it Anyway&lt;/a&gt;. Quick plug for Adam’s new start-up &lt;a href="https://www.crowdfunder.co.uk/fidlleaf" rel="noopener noreferrer"&gt;FidlLeaf: Wellbeing + Personal Growth Platform&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  My turning point
&lt;/h2&gt;

&lt;p&gt;The turning point for me was public speaking. It’s something I have had a fear of for as long as I can remember. But at the same time it’s something that I have always wanted to be able to do.&lt;/p&gt;

&lt;p&gt;There were a lot of things I knew I could do to make it easier, from how to find the right subject matter, an event with a supportive crowd and how to practice it until I was confident I could deliver. With the help of my manager at the time and one of our Coaches we broke down all the things I could do into a plan and a series of small steps to get there.&lt;/p&gt;

&lt;p&gt;I started small, a lightning talk with one other Engineer that was mostly a demo. Then another shared talk that was more of a technical explanation. Each time these were practiced and rehearsed, they were delivered to an audience of friendly Potatoes (not literally, that’s just how we refer to ourselves at Potato) who were supportive and gave feedback when it was asked for.&lt;/p&gt;

&lt;p&gt;The next challenge I gave myself was to take a ridiculous subject and still try to make a 5 minute solo talk about it engaging and entertaining for the audience. I delivered a lightning talk titled "Crumpets and Crumpet-Based Life Hacks" and to this day it’s probably the best received talk that I have delivered.&lt;/p&gt;

&lt;p&gt;Finally I found a suitable event to deliver my first public talk at. Potato were hosting &lt;a href="https://twitter.com/djugl" rel="noopener noreferrer"&gt;DJUGL&lt;/a&gt;’s lightning talk events, so the location and a good proportion of the audience would be familiar to me. I prepared a talk about &lt;a href="https://medium.com/potato/search?q=work%20experience" rel="noopener noreferrer"&gt;the work experience programme we’d been running at Potato&lt;/a&gt; that year, why I felt it was so important, and trying to encourage other companies to give it a go. I practiced a lot (both solo and in front of others), refined it with their feedback, and got to the point where I had learned my speech off-by-heart. I knew I could do all of these things to help myself feel more prepared for it and take the edge of the anxiety. But the thing that really surprised me was that after all of this practice, I no longer felt anxious about the public speaking. I was actually excited to share what I had learned and possibly encourage others to do the same.&lt;/p&gt;

&lt;p&gt;This is why it was such a turning point for me. I realised that I was capable, through a bit of hard work and perseverance, of no longer experiencing anxiety about something that used to cause me significant anxiety. It made therapy seem like a much more viable option for me.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting help
&lt;/h2&gt;

&lt;p&gt;Asking for help was possibly the single hardest thing I had to do. I was in a very fortunate situation at Potato. We have access to &lt;a href="https://nabs.org.uk/" rel="noopener noreferrer"&gt;NABS&lt;/a&gt; who, among a whole host of other services, offer a series of free therapy sessions to people who need it.&lt;/p&gt;

&lt;p&gt;As part of this you have to ring up and speak to someone on the phone and explain the difficulties you’re experiencing and why you would like help with them. I have always found it difficult to talk about my anxiety. I think for me there’s a real sense of shame associated with it, and feeling like I’m failing at something that everyone else is coping fine with (which isn’t true). I get choked up and emotional when I talk about my experiences. In part I relive them as I talk, and getting choked-up for me made it even more difficult, because I was terrified of someone seeing the crack in the facade.&lt;/p&gt;

&lt;p&gt;I’m working on this one in therapy, still. I know it’s okay to feel and to express my emotions. I’m sharing a lot more openly about it. But I notice how much my view was shaped by the world I grew up in. This bullshit concept of "big boys don’t cry" that was perpetuated in 90s pop-culture, where a man who expressed his emotions was either a woman or gay. It’s wrong on so many levels.&lt;/p&gt;

&lt;p&gt;I hid myself away in one of our smallest meeting rooms in the office for that call, and I’m not ashamed to say that I spent the 15 minutes I had after it ended bawling my eyes out. Then composing myself so that nobody else would see. I’ll throw in a quick thank you here to the person who dropped everything they were doing to get me through that evening, and their ongoing support in my journey. I won’t name them, but it’s an easy guess.&lt;/p&gt;

&lt;h3&gt;
  
  
  Ongoing support at work
&lt;/h3&gt;

&lt;p&gt;Talking about my mental health in a professional context felt like a really big deal at the time, but it went far more smoothly than I thought. &lt;/p&gt;

&lt;p&gt;I spoke directly to our Tech Director and Head of People about it, and honestly the reaction was incredible (thank you Luke &amp;amp; Steph). They told me to make my well-being the top priority. We’d reduce my workload as needed, and I could be completely flexible with my working hours. I was given the freedom to fit my work in around the way I was feeling on any given day and take time out for my therapy sessions in the middle of the day. I was encouraged to take more breaks. We already have an uncounted paid leave policy at Potato, but being told to make more use of it really helped to eliminate any of the guilt I was feeling for taking a week off just to recharge at home without going anywhere.&lt;/p&gt;

&lt;p&gt;I was able to do this for as long as I felt I needed to, with no pressure at all from work. I’m mostly working as normal again now, although I still finish early on Tuesdays for therapy.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I’m doing to manage things now
&lt;/h2&gt;

&lt;p&gt;I’m in a much better place than I was this time last year. I remember on the previous World Mental Health Day wanting to simply tweet out that anxiety was something I was dealing with, and even the thought of that filled me with dread at the time. Now I feel (mostly) comfortable sharing my story publicly, and more than that, I actively want to. Through sharing, I hope to be able to help others in some way, or at the very least normalise the idea of mental health a tiny bit more.&lt;/p&gt;

&lt;p&gt;I’m still going to therapy. I started with CBT, learning some skills I can use to manage my anxiety when I experience it. Now I’m doing Psychotherapy with the same therapist to look at some of the underlying reasons that I’m experiencing it and work through them. I don’t see myself stopping this any time in the near future, and I’m totally okay with this.&lt;/p&gt;

&lt;p&gt;I have formed a bunch of healthy habits that are helping me to manage things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Journaling&lt;/strong&gt; - I journal very often, most evenings. Just writing down all the things that are on my mind, challenging my overly negative thoughts and occasionally writing myself a letter as if I was talking to a close friend who was going through this (we can be way harsher to ourselves than we would be to anyone else).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Gratitude&lt;/strong&gt; - I keep a gratitude journal. At the end of each day I try to write down 3 good things that happened, or that I’m thankful for that day. I’m up to about 700 entries now.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;"Yay me" book&lt;/strong&gt; - This is something I’ve only recently started (the name inspired by a former Coach Community Lead at Potato). Essentially I’m gathering some of the nice things or successes that either I have thought about myself or have heard from others. I’m grouping them roughly into areas (like professional, personal, relationships) so that if I’m feeling negative, I have a source of positivity to balance things out.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Exercise&lt;/strong&gt; - I’m a big believer of "healthy body, healthy mind". I used to say that I went a little crazy if it had been more than a week without riding my bike. Last year I took up running as it’s a bit easier to fit into the day. Until I started therapy, doing some hard cardio every couple of days was my crutch. Then I got quite ill and everything fell apart. These days I try and fit in a couple of runs and a couple of workouts each week.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Mindfulness / meditation / yoga&lt;/strong&gt; - Definitely something I’d like to do more of. I meditate only really when I want to calm down, but it’s effective. I started the &lt;a href="https://www.youtube.com/playlist?list=PLui6Eyny-UzwxbWCWDbTzEwsZnnROBTIL" rel="noopener noreferrer"&gt;30 days of Yoga with Adriene&lt;/a&gt; early in lockdown but haven’t finished it yet. Mindfulness is a huge topic, but for me focusing on my breathing is really something that helps bring me back into the moment when I’m spiraling. I’m a big fan of &lt;a href="https://www.verywellmind.com/the-benefits-and-steps-of-box-breathing-4159900" rel="noopener noreferrer"&gt;box breathing&lt;/a&gt; and count out the seconds by tapping on my finger tips in turn to add extra mental focus.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Being more open&lt;/strong&gt; - this was a tough habit to form for me. I have generally been quite guarded and have spent many years absolutely terrified of people finding out about my anxiety. But hiding it away reinforces the idea that there &lt;em&gt;is&lt;/em&gt; something to hide, that there’s something wrong or to be ashamed of. There isn’t. I took baby steps to begin with, I would answer truthfully if directly asked. Then I made the therapy block in my calendar visible to others, I started mentioning it in conversation when relevant. Now this post. It’s something I’m still working on, but I’m really proud of the progress I’ve made.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On that last point. I want to thank the two guys at Potato who really changed my perspective on this. It was late January, we were in a &lt;a href="https://pc3coachingtoolkit.pbworks.com/w/page/54101472/The%20Triad%20Model" rel="noopener noreferrer"&gt;coaching triad&lt;/a&gt;, I had just started Therapy and wasn’t in a good place at all. When I was asked how I was at the start of the session, I pretty much just broke down into tears, the mask I wore at work came off completely. They handled it really well. At the end of the session one of them commented on how they had no idea I was going through something like that. That it helped them to see that other people had bad days too, and see someone else finding things tough. It helped to normalise what they felt at times. That conversation was probably the biggest inspiration for this post.&lt;/p&gt;

&lt;p&gt;Also, I highly recommend the &lt;a href="https://woebothealth.com/" rel="noopener noreferrer"&gt;free mental health chatbot app: Woebot&lt;/a&gt;. It encourages you to check in, teaches you about various little techniques you can use for self-care, helps you form healthy habits and generally is packed with great little bits of information and encouragement.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;There’s a lot more I could write in this post (there are also many more people I would like to thank), if there’s interest then I’ll gladly do a follow-up. Mainly this was an exercise for me in sharing, and reinforcing to myself that there is no shame in the journey I have gone through, that it’s nothing to hide. I tried to give it a reasonable narrative so that it flowed a bit more naturally than the jumble of thoughts that I wanted to get down. If you take one thing away from this article, let it be this: It’s okay not to feel okay, but you don’t &lt;em&gt;have&lt;/em&gt; to stay feeling like that, and you are &lt;em&gt;not&lt;/em&gt; alone.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Photo by &lt;a href="https://unsplash.com/@finnnyc?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Finn&lt;/a&gt; on &lt;a href="https://unsplash.com/?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>mentalhealth</category>
      <category>anxiety</category>
      <category>story</category>
      <category>career</category>
    </item>
    <item>
      <title>Server Side Rendering React App with Deno</title>
      <dc:creator>Francesco Leonardi</dc:creator>
      <pubDate>Wed, 24 Jun 2020 12:42:08 +0000</pubDate>
      <link>https://forem.com/akqa_leap/server-side-rendering-react-app-with-deno-14nd</link>
      <guid>https://forem.com/akqa_leap/server-side-rendering-react-app-with-deno-14nd</guid>
      <description>&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;Two of my favourites things are React and dinosaurs.&lt;br&gt;
In this article I will show how I’ve put them together to develop a server side rendering &lt;a href="https://reactjs.org/" rel="noopener noreferrer"&gt;React&lt;/a&gt; application with &lt;a href="https://deno.land/" rel="noopener noreferrer"&gt;Deno&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Project Setup
&lt;/h2&gt;

&lt;p&gt;I will assume that we are all familiar with React and Deno. Knowing that Deno is pretty new, if you don’t know how to install it and how it works, I would highly suggest you to have a read at this great &lt;a href="https://dev.p.ota.to/post/an-introduction-to-deno-4u3suut77w6/" rel="noopener noreferrer"&gt;introduction&lt;/a&gt; before diving into this article.&lt;/p&gt;

&lt;p&gt;Now let’s start creating the project structure and the files needed for this tutorial, I’m using &lt;a href="https://code.visualstudio.com/" rel="noopener noreferrer"&gt;Visual Studio Code&lt;/a&gt; but any editor will do.&lt;br&gt;
Open your terminal and type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;deno-react-ssr &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd&lt;/span&gt; &lt;span class="nv"&gt;$_&lt;/span&gt;
code &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will create a new folder called &lt;code&gt;deno-react-ssr&lt;/code&gt; and will open it with vscode.&lt;br&gt;
In this folder we will need to create three files, &lt;code&gt;app.tsx&lt;/code&gt; that will contain the code of the React component, &lt;code&gt;server.tsx&lt;/code&gt; for the server code and &lt;code&gt;deps.ts&lt;/code&gt; will contain all our dependencies. Think of it as our version of a &lt;code&gt;package.json&lt;/code&gt;.&lt;br&gt;
You will end up with a structure 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;.
├── app.tsx
├── deps.ts
└── server.tsx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;In &lt;code&gt;deps.ts&lt;/code&gt; we will have to export all the dependencies needed for this application to run.&lt;br&gt;
Copy the following code and add it to your file.&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;// @deno-types="https://deno.land/x/types/react/v16.13.1/react.d.ts"&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://jspm.dev/react@16.13.1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// @deno-types="https://deno.land/x/types/react-dom/v16.13.1/server.d.ts"&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;ReactDOMServer&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://jspm.dev/react-dom@16.13.1/server&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ReactDOMServer&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Application&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Router&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://deno.land/x/oak@v4.0.0/mod.ts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


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

&lt;/div&gt;



&lt;p&gt;As you can see, in Deno you import the modules directly from a url. &lt;br&gt;
I’ve decided to import React and ReactDOMServer from &lt;a href="https://jspm.org/" rel="noopener noreferrer"&gt;jspm&lt;/a&gt; as suggested in the &lt;a href="https://deno.land/#third-party-modules" rel="noopener noreferrer"&gt;documentation for third party modules&lt;/a&gt; but you can use any other CDN that provides the same modules.&lt;/p&gt;

&lt;p&gt;One unusual thing that may stand out to you could be this:&lt;br&gt;&lt;br&gt;
&lt;code&gt;// @deno-types="https://deno.land/x/types/react/v16.13.1/react.d.ts"&lt;/code&gt;&lt;br&gt;&lt;br&gt;
Since we are using typescript, this line of code will inform Deno of the location of the types it needs to import and will affect the &lt;code&gt;import&lt;/code&gt; statement that follows. A more exhaustive explanation can be found in the &lt;a href="https://deno.land/manual/getting_started/typescript#compiler-hint" rel="noopener noreferrer"&gt;Deno Type Hint&lt;/a&gt; manual.&lt;/p&gt;

&lt;p&gt;I’ve also decided to use &lt;a href="https://github.com/oakserver/oak" rel="noopener noreferrer"&gt;Oak&lt;/a&gt;, a middleware framework for &lt;a href="https://doc.deno.land/https/deno.land/std/http/mod.ts" rel="noopener noreferrer"&gt;Deno's http server&lt;/a&gt; that also provides a router, so I’m importing all the modules we will use in the server in addition to the &lt;code&gt;Context&lt;/code&gt; type that typescript requires.&lt;/p&gt;
&lt;h2&gt;
  
  
  Create your React component
&lt;/h2&gt;

&lt;p&gt;This is how our &lt;code&gt;app.tsx&lt;/code&gt; component will look:&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./deps.ts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;garden&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;green&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;auto&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;fontSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;30px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;maxWidth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;400px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;20px 5px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;100%&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;pure-g pure-u&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h2&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;My&lt;/span&gt; &lt;span class="nx"&gt;DenoReact&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h2&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;pure-button&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;count&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="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Add&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="err"&gt;🦕&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;your&lt;/span&gt; &lt;span class="nx"&gt;garden&lt;/span&gt;&lt;span class="o"&gt;!&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;garden&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nc"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;🦕&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/span&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="sr"&gt; &lt;/span&gt;&lt;span class="err"&gt;}
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;As with any standard React component, we start by importing React from our &lt;code&gt;deps.ts&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;Then we are going to declare our App component that uses &lt;a href="https://reactjs.org/docs/hooks-intro.html" rel="noopener noreferrer"&gt;hooks&lt;/a&gt; to implement a simple button counter that allows you to add as many dinosaurs as you want in your personal garden!&lt;/p&gt;

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

&lt;p&gt;For the server I’m using &lt;a href="https://github.com/oakserver/oak" rel="noopener noreferrer"&gt;Oak&lt;/a&gt; and the code in &lt;code&gt;server.tsx&lt;/code&gt; will look like this:&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;Application&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;ReactDOMServer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;Router&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./deps.ts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./app.tsx&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;PORT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;8008&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Application&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;jsBundle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/main.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;js&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
&lt;span class="s2"&gt;`import React from "https://jspm.dev/react@16.13.1";
 import ReactDOM from "https://jspm.dev/react-dom@16.13.1";
 const App = &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;;
 ReactDOM.hydrate(React.createElement(App), document.getElementById('app'));`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  


&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;html&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="s2"&gt;`&amp;lt;html&amp;gt;
    &amp;lt;head&amp;gt;
      &amp;lt;link rel="stylesheet" href="https://unpkg.com/purecss@2.0.3/build/pure-min.css"&amp;gt;
      &amp;lt;script type="module" src="&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;jsBundle&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;/head&amp;gt;
    &amp;lt;body&amp;gt;
      &amp;lt;main id="app"&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;ReactDOMServer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;renderToString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/main&amp;gt;  
    &amp;lt;/body&amp;gt;
  &amp;lt;/html&amp;gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;router&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Router&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;router&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text/html&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;html&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;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;jsBundle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;application/javascript&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;js&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;allowedMethods&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Listening on port &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;PORT&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;...`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PORT&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As always we need to import all the dependencies we will use in our server. &lt;br&gt;
We will also import our App we created earlier, as you can see the extension &lt;code&gt;.tsx&lt;/code&gt; is required in Deno so don’t forget it!&lt;br&gt;&lt;br&gt;
Next step is to create our Oak server application and we’ll also need to define some routes:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;'/'&lt;/code&gt; will serve our HTML page that contains the rendered app.
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;'/main.js'&lt;/code&gt;  will serve our application code that is needed to &lt;a href="https://reactjs.org/docs/react-dom.html#hydrate" rel="noopener noreferrer"&gt;hydrate&lt;/a&gt; the client side React application.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Finally we tell our application to use the route we just created and start listening on port &lt;code&gt;8008&lt;/code&gt;. You can notice I’m also using &lt;code&gt;router.allowedMethods()&lt;/code&gt;, it’s a middleware that lets the client know when a route is not allowed.&lt;/p&gt;
&lt;h2&gt;
  
  
  Run the application
&lt;/h2&gt;

&lt;p&gt;Running the SSR React application we just created is extremely simple, you just need to use the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;deno run &lt;span class="nt"&gt;--allow-net&lt;/span&gt; ./server.tsx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Deno is built secure by default, that means that a Deno application will not be able to access your network, to overcome this we'll just need to use Deno's &lt;code&gt;--allow-net&lt;/code&gt; flag.&lt;br&gt;&lt;br&gt;
Now the only thing missing is to open &lt;code&gt;http://localhost:8008/&lt;/code&gt; and enjoy your new App!&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;I hope you enjoyed the brief tutorial illustrated in this article and I’m looking forward to seeing what will happen next and how more complex applications can be built with this stack.&lt;/p&gt;

&lt;p&gt;If you are still unclear about anything we’ve done or want a full reference of the code, here’s the &lt;a href="https://github.com/fleonard/deno-react-ssr" rel="noopener noreferrer"&gt;GitHub repository&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>react</category>
      <category>deno</category>
      <category>typescript</category>
      <category>javascript</category>
    </item>
    <item>
      <title>An Introduction to Deno</title>
      <dc:creator>David Gauld</dc:creator>
      <pubDate>Wed, 03 Jun 2020 08:53:46 +0000</pubDate>
      <link>https://forem.com/akqa_leap/an-introduction-to-deno-4dko</link>
      <guid>https://forem.com/akqa_leap/an-introduction-to-deno-4dko</guid>
      <description>&lt;p&gt;Since its introduction in 2009, Node.js has gained huge popularity and usage. But with that, issues with its ecosystem, feature adoption and dependency bloat have started to surface.&lt;/p&gt;

&lt;p&gt;So, in true JavaScript community style, there's a new kid on the block: &lt;a href="https://deno.land" rel="noopener noreferrer"&gt;Deno&lt;/a&gt; 🦕&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Deno?
&lt;/h2&gt;

&lt;p&gt;Deno is a new runtime for JavaScript and Typescript, built on Google's &lt;a href="https://v8.dev/" rel="noopener noreferrer"&gt;V8 engine&lt;/a&gt; and written in &lt;a href="https://www.rust-lang.org/" rel="noopener noreferrer"&gt;Rust&lt;/a&gt;. It was started by Ryan Dahl (who famously started Node.js) as an answer to the problems he saw with Node.js and its ecosystem.&lt;/p&gt;

&lt;p&gt;Ryan announced the project a couple of years ago at JSConf EU during a talk in which he went into some detail about regrets he had over Node.js, particularly around decisions he did (or didn't) make along the way. It's definitely &lt;a href="https://www.youtube.com/watch?v=M3BM9TB-8yA" rel="noopener noreferrer"&gt;worth a watch&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Although seen as a Node.js successor, there are some major differences between the two:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Deno has no package manager.&lt;/li&gt;
&lt;li&gt;Deno implements a security sandbox via permissions.&lt;/li&gt;
&lt;li&gt;Deno has a standard library for common tasks.&lt;/li&gt;
&lt;li&gt;Deno has first-class TypeScript support.&lt;/li&gt;
&lt;li&gt;Deno &lt;em&gt;will&lt;/em&gt; be able to be &lt;a href="https://github.com/denoland/deno/issues/986" rel="noopener noreferrer"&gt;compiled into a single executable&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  No package manager
&lt;/h3&gt;

&lt;p&gt;Instead of the complex module resolution that Node.js supports, Deno simply uses URLs for dependencies and doesn't support package.json. Import a relative or absolute URL into your project, and it'll be cached for future runs:&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;listenAndServe&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://deno.land/std/http/server.ts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Third party modules can be added to Deno's website via &lt;a href="https://deno.land/x/" rel="noopener noreferrer"&gt;https://deno.land/x/&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Security
&lt;/h3&gt;

&lt;p&gt;By default, a Deno application will not be able to access things like your network, environment or file system. Unlike Node.js, in order to give an application access to this sandboxed functionality you'll need to use one of the provided flags:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;deno run server.ts &lt;span class="nt"&gt;--allow-write&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can see all of Deno's supported security flags by running &lt;code&gt;deno run --help&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Standard library
&lt;/h3&gt;

&lt;p&gt;Much like Go, the Deno team maintains a core, stable set of utilities in the form of a standard library. These cover utilities such as logging, http serving and more. If you need to implement a feature, it's probably best to check the standard library first to see if it's already supported.&lt;/p&gt;

&lt;p&gt;You can see what's available in Deno's standard library &lt;a href="https://deno.land/std" rel="noopener noreferrer"&gt;via its source code&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  TypeScript
&lt;/h3&gt;

&lt;p&gt;Unlike Node.js, Deno has first-class support for TypeScript (most of its standard library is written in it). This means that ES modules and all the goodness of static typing are available right from the start, with no transpilation required on the user side. It's worth noting however that Deno still needs to compile TypeScript to JavaScript behind the scenes, and as such incurs a performance hit at compile time unless the module's already been compiled and cached.&lt;/p&gt;

&lt;p&gt;If you'd rather not use TypeScript, Deno supports JavaScript files too.&lt;/p&gt;

&lt;h3&gt;
  
  
  Single executables
&lt;/h3&gt;

&lt;p&gt;Although not implemented yet, one future ambition is to allow a Deno application to be compiled down into a single executable. This could vastly improve and simplify the distribution of JavaScript-based applications and their dependencies.&lt;/p&gt;

&lt;p&gt;You can &lt;a href="https://github.com/denoland/deno/issues/986" rel="noopener noreferrer"&gt;track the progress of single executable compilation&lt;/a&gt; on GitHub.&lt;/p&gt;

&lt;h2&gt;
  
  
  Running Deno
&lt;/h2&gt;

&lt;p&gt;Now we know what Deno is, let's have a play with it.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://deno.land" rel="noopener noreferrer"&gt;Deno website&lt;/a&gt; provides plenty of installation options, but since I'm using macOS I'll use &lt;a href="https://brew.sh/" rel="noopener noreferrer"&gt;Homebrew&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;brew &lt;span class="nb"&gt;install &lt;/span&gt;deno
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once installed, &lt;code&gt;deno&lt;/code&gt; should be available to use from your terminal. Run &lt;code&gt;deno --help&lt;/code&gt; to verify the installation and see what commands it provides.&lt;/p&gt;

&lt;p&gt;Deno also gives the ability to run applications with just a single source URL. Try running the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;deno run https://deno.land/std/examples/welcome.ts

Download https://deno.land/std/examples/welcome.ts
Warning Implicitly using master branch https://deno.land/std/examples/welcome.ts
Compile https://deno.land/std/examples/welcome.ts
Welcome to Deno 🦕
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Deno downloads the module from the provided URL, compiles it and runs the application. If you &lt;a href="https://deno.land/std/examples/welcome.ts" rel="noopener noreferrer"&gt;visit the above module's URL in your browser&lt;/a&gt;, you'll notice that Deno also provides a nice browser UI for the module's source code, which in this case is a simple console.log statement.&lt;/p&gt;

&lt;p&gt;Of course running arbitrary third party code like this should always be treated with caution, but since it's an official Deno example we're all good here, and as mentioned above, Deno's security flags should help limit any potential damage.&lt;/p&gt;

&lt;p&gt;You'll also notice that if you run the same command again, the &lt;code&gt;welcome.ts&lt;/code&gt; module &lt;em&gt;isn't&lt;/em&gt; redownloaded. This is because Deno caches modules when they're first requested, allowing you to continue work on your project in places with limited internet access.&lt;/p&gt;

&lt;p&gt;If for any reason you want to reload any of your imports, you can force this by using the &lt;code&gt;--reload&lt;/code&gt; flag:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;deno run &lt;span class="nt"&gt;--reload&lt;/span&gt; https://deno.land/std/examples/welcome.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Building your first Deno app
&lt;/h2&gt;

&lt;p&gt;To demonstrate a few of Deno's features, let's dive into a simple API example. Nothing too complicated, just a couple of endpoints. And in true Potato style, we'll use different types of spuds for our test data.&lt;/p&gt;

&lt;p&gt;It's worth noting beforehand that this demo won't rely on any third party modules, and will use an in-memory data store. There are plenty of libraries (some are linked at the bottom of this article) that aim to make this simpler, but for now let's stick with vanilla Deno!&lt;/p&gt;

&lt;h3&gt;
  
  
  Setting up the server
&lt;/h3&gt;

&lt;p&gt;Firstly, let's create a TypeScript file. Don't worry too much if you're not familiar with TypeScript, you can use plain JavaScript too. I'll create mine at &lt;code&gt;server.ts&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Next, we need to set up a simple web server. As we've already seen, Deno has a standard library that contains some useful functions with one of these being the &lt;a href="https://deno.land/std/http/" rel="noopener noreferrer"&gt;http module&lt;/a&gt;. Taking inspiration from Go, there's a helpful &lt;code&gt;listenAndServe&lt;/code&gt; function that we can use:&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;listenAndServe&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;ServerRequest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://deno.land/std/http/server.ts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nf"&gt;listenAndServe&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;8080&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ServerRequest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;respond&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;204&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Listening on port 8080.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What's happening here? Firstly, we import the &lt;code&gt;listenAndServe&lt;/code&gt; method from Deno's http module, and the &lt;code&gt;ServerRequest&lt;/code&gt; interface to allow TypeScript type checking. Then, we create a simple server that listens on port 8080 and responds to all requests with a &lt;code&gt;HTTP 204 No Content&lt;/code&gt; response.&lt;/p&gt;

&lt;p&gt;As mentioned above, by default Deno will prevent our application from accessing the network. To run this successfully, we'll need to use Deno's &lt;code&gt;--allow-net&lt;/code&gt; flag:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;deno run &lt;span class="nt"&gt;--allow-net&lt;/span&gt; server.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can verify our application is running correctly using cURL in another terminal tab:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;curl &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="nt"&gt;-X&lt;/span&gt; GET http://localhost:8080

HTTP/1.1 204 No Content
content-length: 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Environment variables
&lt;/h3&gt;

&lt;p&gt;To show how environment variables are passed to Deno, let's add support for a dynamic port number since this is a common use case amongst production servers. Deno provides the &lt;code&gt;Deno.env&lt;/code&gt; runtime library to help with retrieving the current environment variables:&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;listenAndServe&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;ServerRequest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://deno.land/std/http/server.ts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;PORT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;8080&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Deno&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toObject&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nf"&gt;listenAndServe&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;parseInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;PORT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ServerRequest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;respond&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;204&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Listening on port &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;PORT&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can now pass a custom port to our application when running it. One thing to note here is that we need to convert the port variable to a number, since all environment variables are passed as strings and &lt;code&gt;listenAndServe&lt;/code&gt; expects a number for the port.&lt;/p&gt;

&lt;p&gt;When running this, we'll also need to use the &lt;code&gt;--allow-env&lt;/code&gt; flag to grant the application access to our environment variables:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ PORT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;6060 deno run &lt;span class="nt"&gt;--allow-net&lt;/span&gt; &lt;span class="nt"&gt;--allow-env&lt;/span&gt; server.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Routes
&lt;/h3&gt;

&lt;p&gt;For the sake of simplicity, we'll implement a very simple router ourselves using a good old fashioned &lt;code&gt;switch&lt;/code&gt; statement.&lt;/p&gt;

&lt;p&gt;Firstly, let's create some empty route handlers. We'll create two: one to allow a new spud type to be added to a list, and another for retrieving the current list. For now, let's return a &lt;code&gt;HTTP 204 No Content&lt;/code&gt; response so that we can test our application along the way:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;createSpud&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ServerRequest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;respond&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;204&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getSpuds&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ServerRequest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;respond&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;204&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;Next, let's create a &lt;code&gt;handleRoutes&lt;/code&gt; method that'll act as our router:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleRoutes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ServerRequest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/spuds&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;switch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;method&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;createSpud&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;GET&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;getSpuds&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&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;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;respond&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;404&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;Here, we're checking every incoming request URL and method, and directing the request to the appropriate function. If neither the URL nor the method matches anything expected, we return a &lt;code&gt;HTTP 404 Not Found&lt;/code&gt; to the user.&lt;/p&gt;

&lt;p&gt;Finally, let's call the &lt;code&gt;handleRoutes&lt;/code&gt; function from our original server and add a &lt;code&gt;try&lt;/code&gt; statement around it to catch any errors and return an appropriate response:&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="nf"&gt;listenAndServe&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;parseInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;PORT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ServerRequest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;handleRoutes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&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="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&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;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;respond&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;500&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;Using a &lt;code&gt;try&lt;/code&gt; statement and catching errors in this way is usually a good idea with Deno, since unlike Node.js a Deno application will exit when it encounters an uncaught error.&lt;/p&gt;

&lt;p&gt;We should now be able to send POST and GET requests to &lt;a href="http://localhost:8080/spuds" rel="noopener noreferrer"&gt;http://localhost:8080/spuds&lt;/a&gt; and get an expected HTTP response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;curl &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="nt"&gt;-X&lt;/span&gt; GET http://localhost:8080

HTTP/1.1 404 Not Found
content-length: 0

&lt;span class="nv"&gt;$ &lt;/span&gt;curl &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="nt"&gt;-X&lt;/span&gt; GET http://localhost:8080/spuds

HTTP/1.1 204 No Content
content-length: 0

&lt;span class="nv"&gt;$ &lt;/span&gt;curl &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://localhost:8080/spuds

HTTP/1.1 204 No Content
content-length: 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Create handler
&lt;/h3&gt;

&lt;p&gt;Next, let's add an in-memory store for our spud types:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;spuds&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In order to process the incoming spud data, we'll need to be able to parse the request's JSON body. Deno doesn't have a built in way of doing this at the time of writing, so we'll use its &lt;code&gt;TextDecoder&lt;/code&gt; class and parse the JSON ourselves:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;createSpud&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ServerRequest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;decoder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;TextDecoder&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;bodyContents&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;Deno&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;readAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;decoder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;bodyContents&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;What's happening here? Essentially, we're first using the &lt;code&gt;Deno.readAll&lt;/code&gt; method to asynchronously read the contents of the request body (a &lt;code&gt;Reader&lt;/code&gt;) as bytes. We then decode that into a UTF-8 string, and finally parse it as JSON. Phew.&lt;/p&gt;

&lt;p&gt;We can then proceed to add the spud type to the store we created earlier, and return a &lt;code&gt;HTTP 201 Created&lt;/code&gt; response. Our final create handler should look something like this:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;createSpud&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ServerRequest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;decoder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;TextDecoder&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;bodyContents&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;Deno&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;readAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;decoder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;bodyContents&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

  &lt;span class="nx"&gt;spuds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;respond&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;201&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;h3&gt;
  
  
  Get handler
&lt;/h3&gt;

&lt;p&gt;To implement our GET handler, we'll essentially reverse the operation we wrote above by using Deno's &lt;code&gt;TextEncoder&lt;/code&gt;. We'll then set the relevant header to "application/json" using Deno's &lt;code&gt;Headers&lt;/code&gt; class and return the spud data with a &lt;code&gt;HTTP 200 OK&lt;/code&gt; response:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getSpuds&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ServerRequest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;encoder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;TextEncoder&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;encoder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;spuds&lt;/span&gt; &lt;span class="p"&gt;}));&lt;/span&gt;

  &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;respond&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Headers&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;content-type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&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;h3&gt;
  
  
  Final application
&lt;/h3&gt;

&lt;p&gt;Our final file should look a bit like this:&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;listenAndServe&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;ServerRequest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://deno.land/std/http/server.ts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;PORT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;8080&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Deno&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toObject&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;spuds&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;createSpud&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ServerRequest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;decoder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;TextDecoder&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;bodyContents&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;Deno&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;readAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;decoder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;bodyContents&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

  &lt;span class="nx"&gt;spuds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;respond&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;201&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;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getSpuds&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ServerRequest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;encoder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;TextEncoder&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;encoder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;spuds&lt;/span&gt; &lt;span class="p"&gt;}));&lt;/span&gt;

  &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;respond&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Headers&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;content-type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&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;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleRoutes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ServerRequest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/spuds&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;switch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;method&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;createSpud&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;GET&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;getSpuds&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&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;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;respond&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;404&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nf"&gt;listenAndServe&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;parseInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;PORT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ServerRequest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;handleRoutes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&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="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&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;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;respond&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;500&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;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Listening on port &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;PORT&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s give this a test:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;curl &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="nt"&gt;--data&lt;/span&gt; &lt;span class="s1"&gt;'{"type": "maris piper"}'&lt;/span&gt; &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://localhost:8080/spuds            

HTTP/1.1 201 Created
content-length: 0

&lt;span class="nv"&gt;$ &lt;/span&gt;curl &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="nt"&gt;--data&lt;/span&gt; &lt;span class="s1"&gt;'{"type": "king edward"}'&lt;/span&gt; &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://localhost:8080/spuds            

HTTP/1.1 201 Created
content-length: 0

&lt;span class="nv"&gt;$ &lt;/span&gt;curl &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="nt"&gt;-X&lt;/span&gt; GET http://localhost:8080/spuds                            

HTTP/1.1 200 OK
content-length: 54
content-type: application/json
&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"spuds"&lt;/span&gt;:[&lt;span class="s2"&gt;"maris piper"&lt;/span&gt;, &lt;span class="s2"&gt;"king edward"&lt;/span&gt;&lt;span class="o"&gt;]}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you'd rather, you can &lt;a href="https://gist.github.com/dcgauld/205218530e8befe4dfc20ade54e7cc84" rel="noopener noreferrer"&gt;view this file as a Gist&lt;/a&gt; or run it directly with the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;deno run &lt;span class="nt"&gt;--allow-net&lt;/span&gt; &lt;span class="nt"&gt;--allow-env&lt;/span&gt; https://gist.githubusercontent.com/dcgauld/205218530e8befe4dfc20ade54e7cc84/raw/9eff7733cf017f33b2bf3144937f97702ae4fc63/server.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We just created our first Deno application!&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Hopefully this article has given you a glimpse into the world of Deno, and some inspiration to start using it for future projects. I'm excited to see what the future holds for the project, especially around things like single file executables and the potential to run certain Deno modules in the browser.&lt;/p&gt;

&lt;p&gt;If you'd like to learn more about it and its features, I'd really recommend giving &lt;a href="https://deno.land/manual/" rel="noopener noreferrer"&gt;the Deno manual&lt;/a&gt; a read.&lt;/p&gt;

&lt;h2&gt;
  
  
  Useful links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://deno.land/std/examples/" rel="noopener noreferrer"&gt;Official Deno examples&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://deno.land/manual/" rel="noopener noreferrer"&gt;Deno manual&lt;/a&gt; (includes information about &lt;a href="https://deno.land/manual/tools/formatter" rel="noopener noreferrer"&gt;Deno’s built in formatter&lt;/a&gt; and &lt;a href="https://deno.land/manual/testing" rel="noopener noreferrer"&gt;testing library&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://deno.land/std" rel="noopener noreferrer"&gt;Deno standard library&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/denolib/awesome-deno" rel="noopener noreferrer"&gt;awesome-deno&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We created our first Deno API with no third party modules, but there are many libraries out there already that aim to simplify that process. Some examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/oakserver/oak" rel="noopener noreferrer"&gt;oak&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/drashland/deno-drash" rel="noopener noreferrer"&gt;deno-drash&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/NMathar/deno-express" rel="noopener noreferrer"&gt;deno-express&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>deno</category>
      <category>node</category>
      <category>rust</category>
      <category>typescript</category>
    </item>
    <item>
      <title>How Potato Code Remotely</title>
      <dc:creator>Luke Benstead</dc:creator>
      <pubDate>Thu, 21 May 2020 08:17:15 +0000</pubDate>
      <link>https://forem.com/akqa_leap/how-potato-code-remotely-557f</link>
      <guid>https://forem.com/akqa_leap/how-potato-code-remotely-557f</guid>
      <description>&lt;p&gt;At the time of writing, we’re in the middle of the COVID-19 lockdown. As with most other companies, the lockdown has required us at &lt;a href="https://p.ota.to/" rel="noopener noreferrer"&gt;Potato&lt;/a&gt; to rapidly change the way we work day-to-day. We’re a tech company, so that has given us a big advantage in this rapid and unsettling change of routine. But as a company, we’ve historically encouraged our engineers to travel into our central London office most of the time. Working from home has always been a perk at Potato, but never the default position.&lt;/p&gt;

&lt;p&gt;Fortunately we’ve been unintentionally preparing for this day by making the right choice of tools. In this post I hope to give an overview of our toolset, and how it’s allowed us to continue to operate as normal.&lt;/p&gt;

&lt;h1&gt;
  
  
  Cloud-First
&lt;/h1&gt;

&lt;p&gt;Right from the beginning of Potato, we’ve always pushed to use tools that are hosted by others. We’ve never wanted to spend our time being sysadmins, and we’ve always resisted the urge to host anything inside our offices. We wanted all of our stuff to be available anywhere, from any platform. In the past the option of running a VPN, and hosting software internally has come up, but we’ve steadfastly refused the temptation to do so - the risk of losing access, of having to maintain it, and of a single point of failure (what if the office burned down?!) were all reasons to avoid it.&lt;/p&gt;

&lt;p&gt;Also, we wanted to make sure that any of our Engineers could deploy any of our projects from anywhere with an Internet connection. In the past we’ve deployed from trains, planes, pubs, and on one occasion a long while back - a locked bathroom (long story!).&lt;/p&gt;

&lt;p&gt;Finally, if anyone ever had their laptop stolen out of the back of a van while climbing (true story), nothing would be lost if everything is saved online.&lt;/p&gt;

&lt;p&gt;For this reason, (along with our Google history) we’ve based all of our internal systems on Google’s GSuite. Potato runs on Google Docs, Sheets, Calendar and of course Gmail. This has given us access to everything from anywhere, and the decision to base everything around GSuite has allowed us to continue working seamlessly despite now all being remote.&lt;/p&gt;

&lt;h1&gt;
  
  
  Slack / Google Meet
&lt;/h1&gt;

&lt;p&gt;For communication, we’ve been long-time users of Slack, (although before this we were pretty sold on Hipchat). As it’s cloud-based we’ve just continued messaging as normal without disruption (though probably making a bit more use of threads to keep things organised).&lt;/p&gt;

&lt;p&gt;For video calls we’ve always used Google Meet (previously Hangouts). The number of ad-hoc catch-ups has increased, and we hold daily drop-in sessions for people who just want a bit of socialising. On Fridays we’ve rebooted our traditional TPIF (Thank Potato It’s Friday) into a virtual mass video call, armed with beverages of choice and reams of friendly banter!&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;a href="https://www.gitlab.com" rel="noopener noreferrer"&gt;GitLab&lt;/a&gt;
&lt;/h1&gt;

&lt;p&gt;A couple of years ago we moved all of our development over to GitLab. The intention was to bring all of our end-to-end product development life-cycle under one tool. Although we had the option of hosting GitLab ourselves, using GitLab.com’s hosting has saved us the overhead of managing it, and of course it means that our project management tools are available from anywhere.&lt;/p&gt;

&lt;p&gt;Now that we’re all a bit more involved in using GitLab directly day-to-day, we’ve also &lt;a href="https://dev.p.ota.to/post/5631671361601536/" rel="noopener noreferrer"&gt;implemented a Chrome/Firefox extension&lt;/a&gt; that makes things a little easier. &lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;a href="https://visualstudio.microsoft.com/services/live-share/" rel="noopener noreferrer"&gt;Visual Studio Code - Live Share&lt;/a&gt;
&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.p.ota.to%2Fimages%2F5640825748848640%2F" 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.p.ota.to%2Fimages%2F5640825748848640%2F" alt="Code editing with Visual Studio Code" width="800" height="630"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The ability to grab another developer to help solve a problem has always been a key part of Potato culture, and historically one that required that other dev to be in the same room. When we were forced into remote working this was one area where we needed to find a new tool to help us, and we did so by using Visual Studio Code’s “Live Share” plugin. This plugin lets you host a programming session that you can invite others to collaborate in (think Google Docs, but for code editing). Combined with a Google Meet call it makes for a great, and simple pair-programming experience.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;a href="https://www.figma.com/" rel="noopener noreferrer"&gt;Figma&lt;/a&gt;
&lt;/h1&gt;

&lt;p&gt;The final tool in our toolbox is Figma. Until recently our designers were heavily invested in using Sketch as their main design tool, but we’d noticed issues even ahead of the lockdown that made this problematic. &lt;/p&gt;

&lt;p&gt;Firstly, it broke the cloud-first rule. Sketch ran locally, saved files locally, and it wasn’t cross-platform which caused a load of headaches for our Linux-using developers. We came up with workarounds for these things (e.g. using the “Measure” plugin for detailed exports, teaching the designers how to use Git etc.) but it never really fitted the culture of Potato.&lt;/p&gt;

&lt;p&gt;Then Figma came along, and not only did the designers find that it was a better tool, but it’s based in the cloud and so is platform-agnostic. &lt;/p&gt;

&lt;h1&gt;
  
  
  Honourable Mentions
&lt;/h1&gt;

&lt;p&gt;In addition to our development toolset, we use a number of other web-based tools day-to-day, these include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.getharvest.com/" rel="noopener noreferrer"&gt;Harvest + Forecast&lt;/a&gt; - for time tracking and project scheduling&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.bamboohr.com/" rel="noopener noreferrer"&gt;Bamboo&lt;/a&gt; - for managing our people&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.trello.com" rel="noopener noreferrer"&gt;Trello&lt;/a&gt; - For workshopping and lightweight task tracking&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.trakstar.com" rel="noopener noreferrer"&gt;TrakStar&lt;/a&gt; - For managing the career progression of our people
# Summary&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There we are, a complete toolset for seamless remote working - that were built up accidentally by just following the rule that our stuff should be accessible from anywhere, and we don’t want to be the ones running it!&lt;/p&gt;

</description>
      <category>development</category>
      <category>engineering</category>
      <category>tools</category>
      <category>remoteworking</category>
    </item>
    <item>
      <title>Parcel and Rust: A WASM Romcom</title>
      <dc:creator>Alex Eales</dc:creator>
      <pubDate>Fri, 15 May 2020 10:37:07 +0000</pubDate>
      <link>https://forem.com/akqa_leap/parcel-and-rust-a-wasm-romcom-545e</link>
      <guid>https://forem.com/akqa_leap/parcel-and-rust-a-wasm-romcom-545e</guid>
      <description>&lt;p&gt;Web Assembly (WASM) and Rust have been growing and evolving over the last couple of years, so what’s it like to use them together?&lt;/p&gt;

&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;I’ve wanted to use Rust and WASM for a while due to a number of reasons: small bundle size, low-level access with reliable performance, and all the perks that come with Rust (strong type safety, zero-cost abstractions, etc.). So, when I was presented with the opportunity of 2 weeks off-project learning, there was no excuse not to give Rust and WASM a try!&lt;/p&gt;

&lt;p&gt;What followed over the next 2 weeks or so was a bit of a programming rollercoaster for me, something all programmers have been through many times. But when it came time to write my experiences up for this article, I noticed there was a pattern, this experience wasn’t just any rollercoaster…it mapped perfectly to the structure of a Romcom! So, to explain and analyse this not officially supported pairing of a web application bundler and a systems programming language, we will be following the standard 10 part Romcom format, for structure and a bit of comedic relief.&lt;/p&gt;

&lt;h1&gt;
  
  
  Part 1: “An Unfulfilled Desire”
&lt;/h1&gt;

&lt;p&gt;Another reason I wanted to use Rust and WASM is because it was new and shiny, plus it would be nice to hook up the Rust program to a nice web interface. One problem, Rust and WASM is only officially supported with Webpack as a bundler. To me, &lt;a href="https://webpack.js.org/" rel="noopener noreferrer"&gt;Webpack&lt;/a&gt; was that Ex in a Romcom, it was never a good relationship and we could never make it work. But, it seemed that it may be a necessary evil to reach my goal of making something using my lost love, Rust.&lt;/p&gt;

&lt;h1&gt;
  
  
  Part 2: “Meet cute”
&lt;/h1&gt;

&lt;p&gt;So, I grudgingly start to clone the Rust WASM Webpack template as I’m flashed back to a previous project, watching myself as I battle with Webpack trying to compile a Single Page App (SPA). The list of dependencies growing with every plugin. I spam Ctrl + C, “No there must be something else” I think. And that's when it hits me, “Parcel! I remember it saying something about WASM?” I think as I quickly navigate to &lt;a href="https://parceljs.org/" rel="noopener noreferrer"&gt;the Parcel website&lt;/a&gt;, and there it is, this is what I have been looking for, and after a quick &lt;code&gt;npm install&lt;/code&gt;, I’m head over heels.&lt;/p&gt;

&lt;h1&gt;
  
  
  Part 3: “Happy Together”
&lt;/h1&gt;

&lt;p&gt;One &lt;code&gt;npm init&lt;/code&gt; and &lt;code&gt;npm install -D parcel-bundler&lt;/code&gt; later and we are off to the races. Parcel supports importing .rs files in JS and TS out of the box so in a simple HTML5 boilerplate with a main.js I do just that. The rust file contains a simple function which when given 2 numbers returns their sum, some extra Rust to tell the compiler not to mangle the function name and it’s done! The JS calls this function and displays the output in the DOM, a simple example but this seems to have everything I need…&lt;/p&gt;

&lt;h1&gt;
  
  
  Part 4: “Obstacles Arise”
&lt;/h1&gt;

&lt;p&gt;But, as with most romcoms, a bump in the road pulls the relationship into question. For Rust and Parcel, this issue was returning or accepting strings in functions. No matter what I did, it wouldn’t work and streams of undefined would plague my console. Although there seemed to be a solution, the well supported &lt;a href="https://github.com/rustwasm/wasm-bindgen" rel="noopener noreferrer"&gt;“wasm_bindgen” package&lt;/a&gt; provides a polyfill for things missing between Rust and JS! So, make a Rust project with a cargo.toml, add the wasm_bingen crate, import and run… oh wait. Parcel doesn’t seem to work with wasm_bindgen even with a &lt;a href="https://www.npmjs.com/package/parcel-plugin-wasmbindgen" rel="noopener noreferrer"&gt;plugin&lt;/a&gt; someone on a &lt;a href="https://github.com/rustwasm/wasm-bindgen/issues/182" rel="noopener noreferrer"&gt;GitHub issue&lt;/a&gt; cites as the solution...what now?&lt;/p&gt;

&lt;h1&gt;
  
  
  Part 5: “The Journey”
&lt;/h1&gt;

&lt;p&gt;After a few minutes of frantic Googling and skim reading GitHub issues and various tutorials on blogs I find an alternative package, stdweb. Seems to have most of the functionality of wasm_bindgen and a handy tutorial with how to set it up with Parcel! A quick switcheroo of the packages in the cargo.toml, some slight code tweaks and we are back on course with strings being returned and received in &lt;a href="https://hello-rust-wasm.alex-eales.com/" rel="noopener noreferrer"&gt;this simple app&lt;/a&gt;. Time to start making something slightly more complex...a simple genetic algorithm simulator!&lt;/p&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%2Fi%2Fpbrc2vqe0xbr40gvatep.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%2Fi%2Fpbrc2vqe0xbr40gvatep.png" alt="Screenshot of Rust WASM say hello page" width="800" height="565"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Part 6: “New Obstacles”
&lt;/h1&gt;

&lt;p&gt;Okay so new project, Parcel - installed, Rust module - created, stdweb - installed lets get this show on the road! In my head the idea is simple, make a struct in Rust to represent the &lt;a href="https://towardsdatascience.com/introduction-to-genetic-algorithms-including-example-code-e396e98d8bf3" rel="noopener noreferrer"&gt;Genetic Algorithm&lt;/a&gt; Simulation, add some methods to it to get the population or simulate a generation, and then simply instantiate and use it in JS. Can’t be too hard surely (foreshadowing)! Lets just make the struct, seems to be instantiating in JS, lets add some methods onto the struct… wait...what? It seems exporting structs is temperamental at best when using stdweb and parcel am I back to square 1 already?&lt;/p&gt;

&lt;h1&gt;
  
  
  Part 7: “The Choice”
&lt;/h1&gt;

&lt;p&gt;All seems lost, I’m out of viable Rust packages to try and have a console littered with errors, is there nothing I can do? In a last ditch effort I tried manually compiling the .wasm file myself and importing it but after 5 edits to the Rust file I can already feel this getting tedious… As I crawl through GitHub issue after GitHub issue webpack comes up again and again as the solution, maybe I need to accept defeat and go back.&lt;/p&gt;

&lt;h1&gt;
  
  
  Part 8: “Crisis”
&lt;/h1&gt;

&lt;p&gt;F*** I’m going to have to use Webpack, I think as I go back to the start and open the Webpack Rust template, defeated.&lt;/p&gt;

&lt;h1&gt;
  
  
  Part 9: “Epiphany”
&lt;/h1&gt;

&lt;p&gt;As the Webpack Rust template repo clones I took to Google one last time, using one of my old searches, hoping for a miracle. Wait, what's this? A GitHub issue about Parcel and WASM_Bindgen which wasn’t there before? The Google search index must have only just found this to be relevant? Hold on, someone has linked &lt;a href="https://github.com/rustwasm/rust-parcel-template" rel="noopener noreferrer"&gt;a template here for Rust, WASM_Bindgen, and Parcel&lt;/a&gt;! Thank the Search Engine Gods the project may be saved!&lt;/p&gt;

&lt;h1&gt;
  
  
  Part 10: “Resolution”
&lt;/h1&gt;

&lt;p&gt;There it was, under my nose the whole time on the &lt;a href="https://github.com/rustwasm" rel="noopener noreferrer"&gt;rustwasm GitHub repository&lt;/a&gt;. I quickly cloned the repo and followed the set-up instructions and it all worked flawlessly. In the end this search had become a real Cinderella story with the perfect match being found on the stroke of midnight.&lt;br&gt;
So now, time to make something cool with it! I didn’t want to focus too much on the front end and slaving over SCSS making it look nice, so I turned to an old friend: &lt;a href="https://tailwindcss.com/" rel="noopener noreferrer"&gt;TailWindCSS&lt;/a&gt;, a utility-first CSS framework which I have set up with PostCSS and Parcel before.  With all that done I build out a simple layout with a side panel for configuring the simulation and a main panel to hold the results of the simulation. After deciding on the look and feel of the page I start to make some TypeScript components for controlling and displaying the simulation.&lt;/p&gt;

&lt;p&gt;Finally after getting the site up and running with some mock data from a simple &lt;code&gt;set_interval&lt;/code&gt; I start to hook it up to the WASM. It ends up being remarkably simple, just import the &lt;code&gt;module&lt;/code&gt; object from the Rust projects’ &lt;code&gt;cargo.toml&lt;/code&gt; and then all the structs and functions are attached to it! A few little tweaks and testing and what do you know, it's all working and converging! A little bit of cleanup and then I deploy it on &lt;a href="https://firebase.google.com/" rel="noopener noreferrer"&gt;Firebase&lt;/a&gt; and it’s &lt;a href="https://colour-ga.wasm.alex-eales.com/" rel="noopener noreferrer"&gt;hosted happily ever after&lt;/a&gt;.&lt;/p&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%2Fi%2F7a3yaig6iqnovzdn6e8o.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%2Fi%2F7a3yaig6iqnovzdn6e8o.png" alt="Screenshot of Rust WASM genetic algorithm simulator" width="800" height="407"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Now this article has been a bit of fun writing in this style and talking about a project I’ve genuinely enjoyed every minute of, and every up and down. But, what is it actually like using Rust and Parcel? I can wholeheartedly say it is a true pleasure...once you find the right resources. Parcel just makes it so easy with no configuration needed for most projects, and although it might not be as fast on larger projects it will give the big dogs a run for their money 9/10 times!&lt;/p&gt;

&lt;p&gt;As for Rust and WASM it was everything I expected and more. Rust has always been a language I have loved programming in and, although it's a challenge, it never gets old. However, if I am to complain about one thing about this experience, it would be the lack of intellisense on the exported JS module. It may not be an issue when you write the tiny Rust file being compiled but I can see this being painful on larger projects using Rust, WASM, and Parcel.&lt;/p&gt;

&lt;p&gt;In conclusion, if you have ever had a little voice telling you to give Rust or WASM a go, I would highly recommend it and maybe consider using Parcel to avoid the emotional rollercoaster I went on to get it done!&lt;/p&gt;

</description>
      <category>rust</category>
      <category>webassembly</category>
      <category>typescript</category>
      <category>javascript</category>
    </item>
    <item>
      <title>GitLab Details Sidebar</title>
      <dc:creator>Michael Strutt</dc:creator>
      <pubDate>Tue, 12 May 2020 10:23:53 +0000</pubDate>
      <link>https://forem.com/akqa_leap/gitlab-details-sidebar-314h</link>
      <guid>https://forem.com/akqa_leap/gitlab-details-sidebar-314h</guid>
      <description>&lt;p&gt;Why and how we created the GitLab Details Sidebar extension for both &lt;a href="https://chrome.google.com/webstore/detail/gitlab-details-sidebar/pmgjbjfdmgljhnnhhoccjgpabhgefnki" rel="noopener noreferrer"&gt;Chrome&lt;/a&gt; and &lt;a href="https://addons.mozilla.org/en-US/firefox/addon/gitlab-details-sidebar/" rel="noopener noreferrer"&gt;Firefox&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The issue at hand
&lt;/h2&gt;

&lt;p&gt;Like many companies, at &lt;a href="https://p.ota.to" rel="noopener noreferrer"&gt;Potato&lt;/a&gt; we use &lt;a href="https://gitlab.com/" rel="noopener noreferrer"&gt;GitLab&lt;/a&gt; as part of our everyday product development workflow. It’s feature-rich, open source and the team are great at taking on feedback and feature requests from the community.&lt;/p&gt;

&lt;p&gt;It seemed however, that one area of GitLab seemed to suit the Engineer mindset much more than it suited the Product mindset. Our Product Leads had a persistent issue with the GitLab boards where they were unable to see or edit descriptions and comments of the issues directly from the board view. This was a feature that those who had previously been familiar with tools such as JIRA particularly struggled with.&lt;/p&gt;

&lt;p&gt;We did a bit of searching around and found that this &lt;a href="https://gitlab.com/groups/gitlab-org/-/epics/383" rel="noopener noreferrer"&gt;issue had already been raised&lt;/a&gt;. It wasn’t in a state where merge requests were being accepted, or the final direction had been decided. So we set about seeing what we could do to address the issue ourselves in as lean a way as possible. A design had already been put together on the issue in question, so we had everything we needed to jump straight into dev tools and start tinkering.&lt;/p&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%2Fgitlab.com%2Fgroups%2Fgitlab-org%2F-%2Fuploads%2F014342d9083ce95c5f9e820d39b9618a%2Fimage.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%2Fgitlab.com%2Fgroups%2Fgitlab-org%2F-%2Fuploads%2F014342d9083ce95c5f9e820d39b9618a%2Fimage.png" alt="Mockup used to build the GitLab Details Sidebar" width="800" height="456"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Rapid prototyping
&lt;/h2&gt;

&lt;p&gt;After exploring a couple of different approaches, it became clear that the fastest way to get a feature-rich details view would be to use the details page itself, leveraging an iframe to include it into the existing sidebar. As well as being simple to execute, this would ensure that any updates to the functionality of the details page would be reflected in our extension. Then it was a case of adding a click event to listen for when an issue was clicked on, and reading the URL for the link to update the source of the iframe.&lt;/p&gt;

&lt;p&gt;The next thing to validate was how to inject the iframe into the page of everyone who wanted it. A Chrome Extension seemed like the obvious candidate here, as most of us use Google Chrome at Potato, and they can be easily &lt;a href="https://extensionworkshop.com/documentation/develop/porting-a-google-chrome-extension/" rel="noopener noreferrer"&gt;ported over to FireFox&lt;/a&gt; to extend the reach (and also to please our Tech Director, Luke). I hadn’t personally built a Chrome Extension before, but a quick bit of research showed that a feature called &lt;a href="https://developer.chrome.com/extensions/content_scripts#declaratively" rel="noopener noreferrer"&gt;Content Scripts&lt;/a&gt; would give us a simple way to inject CSS and JS files onto pages that match our URL pattern.&lt;/p&gt;

&lt;h2&gt;
  
  
  Defining the MVP
&lt;/h2&gt;

&lt;p&gt;Once we’d proved to ourselves that this was possible, and we had a sensible direction in place, we wanted to define the minimum set of requirements that would make this extension useful. The goal was to get this to real users at Potato and see if we can improve the workflow for our Product Leads. After a quick brainstorming session, the set we came up with was:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ability to see and interact with the issue details view directly from the board&lt;/li&gt;
&lt;li&gt;Option to toggle the expanded details view&lt;/li&gt;
&lt;li&gt;Expanded state should persist between tickets and on reload&lt;/li&gt;
&lt;li&gt;Users should still be able to interact with the full board in the background&lt;/li&gt;
&lt;li&gt;Expanded view is not appropriate for small screens&lt;/li&gt;
&lt;li&gt;Details view should have a stripped back UI to integrate better into the sidebar&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Polishing up the MVP
&lt;/h2&gt;

&lt;p&gt;We had a few things to do to get from the proof of concept that we were copy-pasting into the developer console to our first release candidate, some of which proved easier than others. &lt;a href="https://gitlab.com/potato-oss/gitlab-details-sidebar/-/commit/da07a08c9eadf09ea501e1edf627091c57bbcbe6" rel="noopener noreferrer"&gt;Saving the toggled state&lt;/a&gt; was simple enough. The toggle relied on flipping a boolean in the code and updating some CSS classes accordingly. &lt;em&gt;localStorage&lt;/em&gt; seemed like a good candidate for the implementation as the extension is installed at a browser level, just like the scope of &lt;em&gt;localStorage&lt;/em&gt;. All that needed to be done to persist the state was writing the new state every time it was changed. Then on initialisation, read this value back from &lt;em&gt;localStorage&lt;/em&gt; (converting between string and boolean).&lt;/p&gt;

&lt;p&gt;One thing that proved more challenging was correctly &lt;a href="https://gitlab.com/potato-oss/gitlab-details-sidebar/-/issues/12" rel="noopener noreferrer"&gt;handling the creation of new issues&lt;/a&gt; on the board. Using Mutation Observer seemed like a good fit for this, and it was a good excuse for me to try it out with a more complicated use-case. Initially this seemed really simple to filter the mutations down to the creation of new cards but there were a few edge cases. Dragging and dropping created clones of each card, but this could be fixed by tracking which issue numbers had been seen before. The final hurdle was to handle the startup when all of the issues were being added to the board asynchronously. We didn’t want this to treat each card being added to the board the same way as a new issue being created. As the cards are added all at once, a simple debouncing of the function handling new cards being added reduced the occurrences down to a single firing of the event that could be safely ignored until user interaction.&lt;/p&gt;

&lt;p&gt;Finally, to get things ready for internal testing, we needed to create a store page, give our extension a name and capture a screenshot of the extension in action.&lt;/p&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.p.ota.to%2Fimages%2F5710353417633792%2F" 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.p.ota.to%2Fimages%2F5710353417633792%2F" alt="GitLab Details Sidebar on the Chrome Web Store" width="800" height="556"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Internal dogfooding &amp;amp; finishing touches
&lt;/h2&gt;

&lt;p&gt;The newly named GitLab Details Sidebar was very well received across the teams at Potato. People across the disciplines found it a useful addition to their workflow and it swiftly became the most installed internal Chrome Extension at Potato. From this use we discovered and fixed a few bugs, and got some good feedback on some potential future enhancements.&lt;/p&gt;

&lt;p&gt;As well as offering some bug fixes, one of my colleagues made a great contribution to speed up the workflow. Using GitLab’s CI pipeline to &lt;a href="https://gitlab.com/potato-oss/gitlab-details-sidebar/-/issues/15" rel="noopener noreferrer"&gt;automate the release process&lt;/a&gt;, uploading a zip file directly to the Chrome Web Store, then publishing the extension via the API. Now anyone in the team can release a successful commit from master without having to build anything locally.&lt;/p&gt;

&lt;h2&gt;
  
  
  Publish to the world
&lt;/h2&gt;

&lt;p&gt;Finally we were ready to share our creation. We included a simple popup-window to show some info about the extension and link back to the &lt;a href="https://gitlab.com/potato-oss/gitlab-details-sidebar/-/boards/1703747" rel="noopener noreferrer"&gt;issue board&lt;/a&gt; and the &lt;a href="https://gitlab.com/potato-oss/gitlab-details-sidebar" rel="noopener noreferrer"&gt;source code&lt;/a&gt; and then change the extension from &lt;em&gt;private&lt;/em&gt; to &lt;em&gt;public&lt;/em&gt; and republished.&lt;/p&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.p.ota.to%2Fimages%2F5646488461901824%2F" 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.p.ota.to%2Fimages%2F5646488461901824%2F" alt="GitLab Details Sidebar info window" width="614" height="433"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can find the GitLab Details Sidebar on the &lt;a href="https://chrome.google.com/webstore/detail/gitlab-details-sidebar/pmgjbjfdmgljhnnhhoccjgpabhgefnki" rel="noopener noreferrer"&gt;Chrome Web Store&lt;/a&gt; and on the &lt;a href="https://addons.mozilla.org/en-US/firefox/addon/gitlab-details-sidebar/" rel="noopener noreferrer"&gt;Add-ons for Firefox&lt;/a&gt; site where you can install it completely free. We fully welcome any feedback or feature requests. Hopefully this extension will improve your daily workflow just as much as it has ours.&lt;/p&gt;

</description>
      <category>gitlab</category>
      <category>opensource</category>
      <category>workflow</category>
      <category>chromeextension</category>
    </item>
  </channel>
</rss>
