<?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: Igor Cekelis</title>
    <description>The latest articles on Forem by Igor Cekelis (@igorcekelis).</description>
    <link>https://forem.com/igorcekelis</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F340926%2F4ea6d521-5914-4537-a361-e8705f691d5f.png</url>
      <title>Forem: Igor Cekelis</title>
      <link>https://forem.com/igorcekelis</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/igorcekelis"/>
    <language>en</language>
    <item>
      <title>How to build a cost-effective Kubernetes disaster recovery plan</title>
      <dc:creator>Igor Cekelis</dc:creator>
      <pubDate>Tue, 10 Aug 2021 10:38:38 +0000</pubDate>
      <link>https://forem.com/barrage/how-to-build-a-cost-effective-kubernetes-disaster-recovery-plan-51i3</link>
      <guid>https://forem.com/barrage/how-to-build-a-cost-effective-kubernetes-disaster-recovery-plan-51i3</guid>
      <description>&lt;p&gt;Every business relies on documents, applications, data and infrastructure to function on a daily basis and losing some of them can have serious consequences. Since the IT world can be quite unpredictable, Disaster Recovery plan is insurance that a business will be up and running as soon as possible.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Planning ahead is key to success
&lt;/h2&gt;

&lt;p&gt;Disaster recovery (DR) involves a set of policies, tools, and procedures that allows us to resume normal operation following a disaster by regaining access to data, hardware, software, network, and other crucial parts of our business.&lt;/p&gt;

&lt;p&gt;One of the most important things when talking about Disaster recovery is RTO (Recovery time objective). RTO is defined as the amount of time it takes for your organization’s infrastructure to come back online and be fully functional in case of a natural or human-induced disaster.&lt;/p&gt;

&lt;p&gt;Disaster Recovery and Business Continuity are close terms but not the same. Business continuity is an organization's ability to ensure operations and core business functions are not severely impacted by a disaster or unplanned incident that takes critical systems offline, whereas Disaster Recovery is all about getting your infrastructure and operations up and running again.&lt;/p&gt;

&lt;p&gt;In this context, we can say that disaster is any unforeseen event that can significantly put your organization at risk by interfering with your daily operations. Of course, not every disaster has to involve a catastrophic destruction scenario, but in order to run a stable and consistent business, it is better to be safe than sorry.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why is an efficient Disaster Recovery plan necessary?
&lt;/h2&gt;

&lt;p&gt;Although most companies tend to the safety of their data, they are more often concerned about data leakage rather than what would happen if all the crucial information suddenly became inaccessible. Natural or human-induced, disasters can happen, and it would be wise for all companies to prepare ahead for such eventualities. &lt;/p&gt;

&lt;p&gt;Our organization started to grow and the number of clients increased, and since we strive to deliver the best service possible to our clients, we had to take all possible scenarios into account.&lt;/p&gt;

&lt;p&gt;Our main problem was a single point of failure for our infrastructure. Namely, production servers were located on the same physical location, and there were backups of all data stored on secured locations but in case of disaster, it would take hours, even days to bring everything back online, and we didn’t want to take those chances.&lt;/p&gt;

&lt;p&gt;So we decided that the best solution to this problem would be to have multiple servers in different locations, and that are in sync with each other.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Building a functional Kubernetes Disaster Recovery on a budget
&lt;/h2&gt;

&lt;p&gt;Building a competitive, enterprise-grade Kubernetes platform requires more than simply deploying your applications. Kubernetes clusters require protection, maintenance, automation, and stability.&lt;/p&gt;

&lt;p&gt;Disaster Recovery for Kubernetes can be both time and budget-consuming, but here we will focus on a "budget" Disaster Recovery plan that is mostly based on open-source software, because we wanted to challenge ourselves and see if we can achieve the same results with much smaller expenses.&lt;/p&gt;

&lt;p&gt;The software that we are using for our Disaster Recovery strategy is open source, and even though most companies are reluctant to use open source software as Disaster Recovery strategy, our experience is quite positive - open source software is not any "less" secure or stable than most enterprise solutions. In addition to that, it offers more freedom to customize it for your organization's needs. One potential downside is that there won’t be any technical support or guarantee from a large enterprise, but truth be told, if you know what you are doing, these elements are unnecessary and not to mention your company would save a lot of money.&lt;/p&gt;

&lt;p&gt;To give you a better insight into dealing with this particular problem, we need to say a few things about infrastructure where this kind of solution was implemented. Targeted infrastructure uses Kubernetes clusters on bare metal machines which gives us full control over our clusters, and production clusters have their own identical replica that is running in separate data centers which allows us to make an easy fail-over if there is any disaster scenario taking place on one of the locations.&lt;/p&gt;

&lt;p&gt;Monitoring our systems and notifications in case of disaster is handled by a combination of software that collects metrics regarding our clusters and sends alerts to our company’s Slack channel, email, and even personal smartphones in some cases.&lt;/p&gt;

&lt;p&gt;Metric collecting is handled by Prometheus, and Prometheus as a collector does a great job providing metrics to Grafana and Alertmanager. Grafana offers various options that you can use to monitor your infrastructure. Also, it allows you to create your custom dashboards.&lt;/p&gt;

&lt;p&gt;For sending alerts and warnings, Alertmanager is one handy tool, and by using metrics collected by Prometheus and a set of custom-defined rules, it will let you know when you are in trouble.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Backups and Data migration
&lt;/h2&gt;

&lt;p&gt;MinIO is the world's fastest object storage server, and a natural fit for companies looking for a consistent, performant, and scalable object store for their hybrid cloud strategies. Kubernetes-native by design, S3 compatible from inception, MinIO has more than 7.7M instances running in AWS, Azure, and GCP today - more than the rest of the private cloud combined. When added to millions of private cloud instances and extensive edge deployments - MinIO is the hybrid cloud leader. Simple, fast, reliable, and open source.&lt;/p&gt;

&lt;p&gt;Velero is an open-source tool to safely backup and restore, perform disaster recovery, and migrate Kubernetes cluster resources and persistent volumes. Also, it reduces time to recovery in case of infrastructure loss, data corruption, and/or service outages.&lt;/p&gt;

&lt;p&gt;Combining MinIO and Velero allows you to sync data between clusters as fast as possible.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Deployment replication
&lt;/h2&gt;

&lt;p&gt;GitLab CI/CD pipeline allows concurrency between deployments, and with the right configuration every pipeline will deploy your applications on multiple clusters at the same time.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Solution
&lt;/h2&gt;

&lt;p&gt;This kind of plan requires minimal human intervention if things go downhill for whatever reason, and as mentioned, the whole strategy is built around reliable, remarkable open-source software.&lt;/p&gt;

&lt;p&gt;The diagram below can give you a raw insight into the solution, one live cluster and another replica of the same cluster waiting in standby, just in case. &lt;/p&gt;

&lt;p&gt;Gitlab CI/CD deploys the app to the production cluster, Velero takes a backup of stateful data (databases) and stores it on production MinIO cluster, that data is replicated to DR MinIO instance and is then restored using Velero to standby cluster in DR site. You can schedule the Velero backup, MinIO replication, and Velero restore actions according to your RPO/RTO parameters. Since we are using BGP to transfer our public IPs, no further steps are needed. If you don't have that option, you can just change your public DNS records.&lt;br&gt;
&lt;br&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jF4ecEhE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.prismic.io/barrage/3f66694f-b4a1-41ed-acef-acb54c971946_kubernetes-disaster-recovery-plan-diagram.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jF4ecEhE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.prismic.io/barrage/3f66694f-b4a1-41ed-acef-acb54c971946_kubernetes-disaster-recovery-plan-diagram.png" alt="alt text"&gt;&lt;/a&gt;&lt;br&gt; A diagram of Kubernetes disaster recovery plan 
 &lt;br&gt;&lt;/p&gt;

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

&lt;p&gt;In order to comply with the ever changing demands of the business world, most companies take data security seriously to make sure nothing leaks outside of the organization and they don’t lose credibility. However, while a damaged reputation is something a company can rebuild, loss of data at an unexpected moment can put a stop to the entire business, sometimes even for good.&lt;/p&gt;

&lt;p&gt;This is why preparing for the unexpected by creating a Disaster Recovery plan is vital to company’s wellbeing - you need to ensure that whatever happens, your business will quickly recover without any significant consequences.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>backup</category>
      <category>disasterrecovery</category>
      <category>datasecurity</category>
    </item>
    <item>
      <title>Async/await operations - a new way of writing asynchronous code</title>
      <dc:creator>Igor Cekelis</dc:creator>
      <pubDate>Mon, 09 Aug 2021 11:38:54 +0000</pubDate>
      <link>https://forem.com/barrage/async-await-operations-a-new-way-of-writing-asynchronous-code-5050</link>
      <guid>https://forem.com/barrage/async-await-operations-a-new-way-of-writing-asynchronous-code-5050</guid>
      <description>&lt;p&gt;Async/await mechanism is the new way to write asynchronous code that you traditionally write with a completion handler (known as closure). Asynchronous functions allow asynchronous code to be written as if it were synchronous. For demonstration purposes, we used Xcode 13 beta with the Swift 5.5 version.&lt;/p&gt;



&lt;h2&gt;
  
  
  A new way of writing asynchronous code
&lt;/h2&gt;

&lt;p&gt;Five main problems that async/await could solve are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pyramid of doom&lt;/li&gt;
&lt;li&gt;Better error handling&lt;/li&gt;
&lt;li&gt;Conditional execution of the asynchronous function&lt;/li&gt;
&lt;li&gt;Forgot or incorrectly call the callback&lt;/li&gt;
&lt;li&gt;Eliminating design and performance issue of synchronous API because of callbacks API awkwardness&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Async await provides the mechanism for us to run asynchronous and concurrent functions in a sequential way which helps us make our code easier to read, maintain and scale, which are very important parameters in &lt;a href="https://www.barrage.net/solutions/custom-software-development" rel="noopener noreferrer"&gt;software development&lt;/a&gt;.&lt;/p&gt;



&lt;h3&gt;
  
  
  Async/await vs. completion handlers
&lt;/h3&gt;

&lt;p&gt;First, we are going to show you how you would traditionally write functions with completion handlers. Everyone is familiar with this approach.&lt;/p&gt;

&lt;p&gt;Don't get us wrong, this isn't a bad way of writing functions with completion handlers. We've been doing it like this for years on our &lt;a href="https://www.barrage.net/work" rel="noopener noreferrer"&gt;projects&lt;/a&gt;; completion handlers are commonly used in Swift code to allow us to send back values after a function returns.&lt;/p&gt;

&lt;p&gt;Still, once you have many asynchronous operations that are nested, it's not really easy for the Swift compiler to check if there is anything weird going on in terms of any bugs introduced into your code.&lt;/p&gt;

&lt;p&gt;For cleaner code, we made a new Swift file called NetworkManager.swift, and in this file, we are handling our requests. Our User is a struct with values of name, email, and username.&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;struct User: Codable {
    let name: String
    let email: String
    let username: String
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// MARK: fetch users with completion handler
func fetchUsersFirstExample(completion: @escaping (Result&amp;lt;[User], NetworkingError&amp;gt;) -&amp;gt; Void) {

    let usersURL = URL(string: Constants.url)

    guard let url = usersURL else {

        completion(.failure(.invalidURL))
        return
    }

    let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
        if let _ = error {
            completion(.failure(.unableToComplete))
        }

        guard let response = response as? HTTPURLResponse, response.statusCode == 200 else {
            completion(.failure(.invalidResponse))
            return
        }

        guard let data = data else {
            completion(.failure(.invalidData))
            return
        }

        do {
            let users = try JSONDecoder().decode([User].self, from: data)
            completion(.success(users))
        } catch {
            completion(.failure(.invalidData))
        }
    }
    task.resume()
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;As you can see, a lot is going on here; it is pretty hard to debug, there is a lot of error handling for "just" fetching user data, and we ended up with a bunch of lines of code. Most programmers needed to write a couple of these in projects, which gets very repetitive and ugly. &lt;/p&gt;

&lt;p&gt;In our ViewController.swift file, we decided to show data inside a table view, so we made one and conformed to its data source. Once we decided to call this function, it would look something 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;//MARK: 1. example -&amp;gt; with completion handlers
private var users = [User]()
​
private func getUsersFirstExample() {
    NetworkManager.shared.fetchUsersFirstExample { [weak self] result in
        guard let weakself = self else { return }

        switch result {
        case .success(let users):
            DispatchQueue.main.async {
                weakself.users = users
                weakself.tableView.reloadData()
            }
        case .failure(let error):
            print(error)
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;h2&gt;
  
  
  Defining and calling an asynchronous function
&lt;/h2&gt;

&lt;p&gt;Now, on the other hand, here is how you would write a function with async/await, which is doing everything like the example above:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//MARK: fetch users with async/await using Result type
func fetchUsersSecondExample() async -&amp;gt; Result&amp;lt;[User], NetworkingError&amp;gt; {
    let usersURL = URL(string: Constants.url)

    guard let url = usersURL else {
        return .failure(.invalidURL)
    }

    do {
        let (data, _) = try await URLSession.shared.data(from: url)
        let users = try JSONDecoder().decode([User].self, from: data)

        return .success(users)
    }
    catch {
        return .failure(.invalidData)
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;An asynchronous function is a special kind of function that can be suspended while it's partway through execution. This is the opposite of synchronous functions, which either run to completion, throw an error, or never return.&lt;/p&gt;

&lt;p&gt;We are using two keywords, async and await.&lt;/p&gt;

&lt;p&gt;We use the async keyword to tell the compiler when a piece of code is asynchronous. And with await keyword, we tell our compiler that it has the option of suspending function until data or error is returned; and to indicate where the function might unblock the thread, similar to other languages such as C# and Javascript.&lt;/p&gt;

&lt;p&gt;Swift APIs, like URLSession, are also asynchronous.&lt;/p&gt;

&lt;p&gt;But then, how do we call an async marked function from within a context that’s not itself asynchronous, such as a UIKit-based view controller?&lt;/p&gt;

&lt;p&gt;What we’ll need to do is to wrap our call in an async closure, which in turn will create a task within which we can perform our asynchronous calls - 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;//MARK: 2. example -&amp;gt; async/await with Result type
private func getUsersSecondExample() {
    async {
        let result = await NetworkManager.shared.fetchUsersSecondExample()

        switch result {
        case .success(let users):
            DispatchQueue.main.async {
                self.users = users
                self.tableView.reloadData()
            }
        case .failure(let error):
            print(error)
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;Result type was introduced in Swift 5.0, and its benefits are to improve completion handlers.&lt;/p&gt;

&lt;p&gt;They become less important now that async/await is introduced in Swift 5.5, of course.&lt;/p&gt;

&lt;p&gt;However, it's not useless (as you can see in the example above) since it's still the best way to store results.&lt;/p&gt;

&lt;p&gt;Here is one more example of usage async/await without Result type, which is even cleaner approach:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//MARK: fetch users with async/await third example, without Result type
func fetchUsersThirdExample() async throws -&amp;gt; [User]{
    let usersURL = URL(string: Constants.url)
    guard let url = usersURL else { return [] }
    let (data, _) = try await URLSession.shared.data(from: url)
    let users = try JSONDecoder().decode([User].self, from: data)
    return users
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;Making a call of an async function in our ViewController.swift file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;override func viewDidLoad() {
    super.viewDidLoad()
    configureTableView()
    async {
        let users = await getUsersThirdExample()
        guard let users = users else { return }
        self.users = users
        self.tableView.reloadData()
    }
}
​
//MARK: 3. example -&amp;gt; async/await without Result type
private func getUsersThirdExample() async -&amp;gt; [User]? {
    do {
        let result = try await NetworkManager.shared.fetchUsersThirdExample()
        return result
    } catch {
        // handle errors
    }
    return nil
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;One more really good thing about the above example is that we can use Swift's default error handling with do, try, catch, even when asynchronous calls are performed.&lt;/p&gt;

&lt;p&gt;As you can see in both our examples, there is no weak self capturing to avoid retain cycles, and there is no need to update UI on the main thread since we have the main actor (@MainActor) who is taking care of that (the main actor is accessible only if you are using Swift's new concurrency pattern).&lt;/p&gt;

&lt;p&gt;And voilà, here is our result:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.prismic.io%2Fbarrage%2Fd8e5a87c-80ec-4f64-a420-5e800ded119a_async-await-operations-6.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%2Fimages.prismic.io%2Fbarrage%2Fd8e5a87c-80ec-4f64-a420-5e800ded119a_async-await-operations-6.png" alt="alt text"&gt;&lt;/a&gt;&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

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

&lt;p&gt;Async/await is just a part of Swift Concurrency options; Apple's SDKs are starting to make heavy use of them. This offers a new way to write asynchronous code in Swift; the only drawback is that it's not compatible with older operating system versions, and we'll still need to interact with other code that doesn't yet use async/await. We hope this article will help you better understand asynchronous programming in Swift.&lt;/p&gt;

&lt;p&gt;If you want to learn more about this pattern, or about everything that was introduced with Swift concurrency, visit Apple's official website and read their documentation. Additionally, you can check out these useful links:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://developer.apple.com/videos/play/wwdc2021/10095/" rel="noopener noreferrer"&gt;Use async/await with URLSession&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.apple.com/videos/play/wwdc2021/10132/" rel="noopener noreferrer"&gt;Meet async/await in Swift&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/apple/swift-evolution/blob/main/proposals/0296-async-await.md" rel="noopener noreferrer"&gt;Swift Evolution Proposal - Async/await (GitHub)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.swift.org/swift-book/LanguageGuide/Concurrency.html" rel="noopener noreferrer"&gt;Swift Programming language - Concurrency&lt;/a&gt;

&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And if you are interested in source code, visit &lt;a href="https://github.com/miranhrupacki/async-await-WWDC21-blog-post" rel="noopener noreferrer"&gt;my GitHub account&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>mobile</category>
      <category>development</category>
      <category>swift</category>
      <category>ios</category>
    </item>
    <item>
      <title>You do Yew: Rust frontend framework that compiles into WebAssembly</title>
      <dc:creator>Igor Cekelis</dc:creator>
      <pubDate>Wed, 28 Jul 2021 11:20:17 +0000</pubDate>
      <link>https://forem.com/barrage/you-do-yew-rust-frontend-framework-that-compiles-into-webassembly-5g2</link>
      <guid>https://forem.com/barrage/you-do-yew-rust-frontend-framework-that-compiles-into-webassembly-5g2</guid>
      <description>&lt;p&gt;The big question is… what is Yew? First of all, it’s a Rust framework, so it must be a tool for developing backend projects. Not at all! Yew is a frontend framework! It uses Rust language and it compiles into WebAssembly so the application runs in the browser.&lt;/p&gt;



&lt;h2&gt;
  
  
  Rust and WebAssembly
&lt;/h2&gt;



&lt;p&gt;The main point of this post is Yew, but as it uses Rust and WebAssembly, a few words about them won’t hurt. &lt;/p&gt;



&lt;p&gt;If you don’t know about Rust, and want to get familiar with it, I suggest reading our blog post about &lt;a href="https://www.barrage.net/blog/technology/rust-programming-language"&gt;Rust programming language&lt;/a&gt; and &lt;a href="https://doc.rust-lang.org/stable/book/"&gt;The Rust Book&lt;/a&gt;. The book contains a lot of information and examples to get you started.&lt;/p&gt;



&lt;p&gt;I will not bug you with big words describing Rust, let’s just say it’s a system programming language that generates machine code with full control of memory use, like C/C++, but safe. “Safe” meaning that it is hard to mess up because the compiler checks every try to access memory and this is what makes it excellent. All in all, when writing “normal” applications, you can use your programming skills in combination with Rust’s unique features (described in the Book), and I think you will be satisfied with the development processes and the result.&lt;/p&gt;



&lt;p&gt;WebAssembly (Wasm) can be referred to as the Assembly, but for the Web. It’s a low-level language running web applications at native-like performance. Rust can compile (also C/C++) into Wasm which enables Rust applications to run on the Web.&lt;/p&gt;



&lt;p&gt;It is efficient and fast, safe, open and debuggable, and part of the open web platform. For more info on Wasm I will refer you to check out their &lt;a href="https://webassembly.org/getting-started/developers-guide/"&gt;docs&lt;/a&gt;.&lt;/p&gt;



&lt;h2&gt;
  
  
  Yew
&lt;/h2&gt;



&lt;p&gt;As I said, Yew is a Rust frontend framework for creating multi-threaded web applications with Wasm but what I haven’t mentioned are Yew’s main features. &lt;/p&gt;

&lt;p&gt;It is a &lt;strong&gt;component-based framework&lt;/strong&gt;, making it easy to build UI, especially for developers who’ve used frameworks like React (I haven’t but it didn’t take me long to learn it). DOM API calls are expensive in this situation, and we are going to have a lot of them. Luckily, Yew minimizes those and offloads processes to the background so it achieves &lt;strong&gt;great performance&lt;/strong&gt;. Wasm isn’t here to replace Javascript, it’s here to empower it. &lt;strong&gt;Javascript interoperability&lt;/strong&gt; allows you to integrate your Yew app with Javascript applications.&lt;/p&gt;

&lt;p&gt;If you like what I wrote so far, you can continue reading my Yew App Walkthrough, and if not, there are alternatives like &lt;a href="https://github.com/chinedufn/percy"&gt;Percy&lt;/a&gt; and &lt;a href="https://github.com/seed-rs/seed"&gt;Seed&lt;/a&gt;.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Simple Yew application walkthrough
&lt;/h2&gt;

&lt;p&gt;The time has come for us to stop talking and start doing. In this walkthrough, I am going to try to give you a brief, but clear overview of Yew projects and concepts on the example of a simple Todo list manager application.&lt;/p&gt;
&lt;h2&gt;
  
  
  Setting up
&lt;/h2&gt;

&lt;p&gt;You need to install some tools to get started. First of all, you need Rust and Rust’s package manager Cargo and for that, follow the Book mentioned in the introduction.&lt;/p&gt;

&lt;p&gt;Then, it’s time to choose the Wasm build tool. There are a number of them and I used the &lt;em&gt;wasm-pack&lt;/em&gt; which is actively maintained and easy to use. These tools are used to package a Wasm file.&lt;/p&gt;

&lt;p&gt;Install the tool with cargo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cargo install wasm-pack
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;Now we can build our app, but we won’t because we don’t have an application yet. Here we specify the target, build name, and the output directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;wasm-pack build --target web --out-name wasm --out-dir ./static
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will also need a server that will host our application. For that, you can use any server of your choosing. I used &lt;code&gt;miniserve&lt;/code&gt;. Here we specify the hosted directory which is the output directory from our build command and tell the server to look for the index page on start.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cargo install miniserve
miniserve ./static --index index.html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;We are all set now with the tooling. Let’s get to the application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating a project
&lt;/h2&gt;

&lt;p&gt;Using &lt;em&gt;cargo&lt;/em&gt;, create a new Rust &lt;strong&gt;library&lt;/strong&gt; and move to the created folder. It’s important to create a library, not a binary.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cargo new --lib todo_app_yew &amp;amp;&amp;amp; cd todo-app_yew
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;Now, we need to depend on &lt;code&gt;yew&lt;/code&gt; and &lt;code&gt;wasm-bindgen&lt;/code&gt;. Go to your &lt;code&gt;cargo.toml&lt;/code&gt; file and add the dependencies. Also you need to specify c &lt;code&gt;rate-type&lt;/code&gt;, which is required by the &lt;code&gt;wasm-pack&lt;/code&gt; we chose earlier.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[package]
name = "todo_app_yew"
version = "0.1.0"
authors = ["Robert Sudec &amp;lt;robert.sudec@barrage.net&amp;gt;"]
edition = "2018"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[lib]
crate-type = ["cdylib", "rlib"]

[dependencies]
yew = { version="0.18"}
wasm-bindgen = "0.2.67"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;h2&gt;
  
  
  Components
&lt;/h2&gt;

&lt;p&gt;Components in Yew and other component-based frameworks are basic elements we use. Each component has its own state and its own way of presenting the state to the DOM. We can create a component by implementing the &lt;code&gt;Component&lt;/code&gt; trait on a struct. Our Todo application will start with a root component called &lt;code&gt;Model&lt;/code&gt;. We need a struct to keep state, and it will hold a &lt;code&gt;link&lt;/code&gt; to itself, but also contain other information on other components (e.g. parent component).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;struct Model {
    link: ComponentLink&amp;lt;Self&amp;gt;,
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;Implementing the &lt;code&gt;Component&lt;/code&gt; trait, we actually make it a component and implement the component lifecycle. Lifecycle consists of 6 methods, and only 4 of them are used (mostly). These are &lt;code&gt;create&lt;/code&gt;, &lt;code&gt;update&lt;/code&gt;, &lt;code&gt;change&lt;/code&gt; and &lt;code&gt;view&lt;/code&gt;. Create method is called on initialization of the component and we receive &lt;code&gt;Properties&lt;/code&gt; and &lt;code&gt;ComponentLink&lt;/code&gt; from the parent component. Properties are optional, and we will talk about them when we use it in the application. View method allows us to attach HTML to the component which will then render according to it. Let’s also save other methods for later.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
impl Component for Model {
    type Message = ();
    type Properties = ();
    fn create(_: Self::Properties, link: ComponentLink&amp;lt;Self&amp;gt;) -&amp;gt; Self {
        Self {
            link,
        }
    }

    fn update(&amp;amp;mut self, msg: Self::Message) -&amp;gt; ShouldRender {
        true
    }

    fn change(&amp;amp;mut self, _props: Self::Properties) -&amp;gt; ShouldRender {
        false
    }

    fn view(&amp;amp;self) -&amp;gt; Html {
        html! {
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;Then there’s the &lt;code&gt;run_app&lt;/code&gt; function. We bind the start of the application using the annotation to this function and we simply mount the &lt;code&gt;Model&lt;/code&gt; component.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#[wasm_bindgen(start)]
pub fn run_app() {
    App::&amp;lt;Model&amp;gt;::new().mount_to_body();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;So now if we write some HTML in the view method and run the app, it should display in the browser. But, for this walkthrough to not be exhausting, let’s think ahead and start on Routing, and we’ll explain stuff as we go.&lt;/p&gt;

&lt;p&gt;Try to build the app using the command from the &lt;em&gt;Setting up&lt;/em&gt; section. You should get a new folder called static with your compiled files. Add the index.html file with the following content.&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!doctype html&amp;gt;
&amp;lt;html lang="en"&amp;gt;
   &amp;lt;head&amp;gt;
       &amp;lt;meta charset="utf-8"&amp;gt;
       &amp;lt;title&amp;gt;Yew Todo App&amp;lt;/title&amp;gt;
       &amp;lt;script type="module"&amp;gt;
           import init from "./wasm.js"
           init()
       &amp;lt;/script&amp;gt;
   &amp;lt;/head&amp;gt;
   &amp;lt;body &amp;gt;&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;Let’s make a &lt;code&gt;Home&lt;/code&gt;component first. Make a new file, copy the template above, rename it to Home, and add some HTML, like a Welcome message. &lt;/p&gt;

&lt;p&gt;Now, the &lt;code&gt;html!&lt;/code&gt; macro can take one root html element, so if you want to have a title and a RouterAnchor, you can wrap them in one &lt;code&gt;div&lt;/code&gt; or you can use &lt;code&gt;&amp;lt;&amp;gt; &amp;lt;/&amp;gt;&lt;/code&gt; tags. Literals need to be wrapped in curly braces and quotes, and if you’re writing Rust code, then wrap it in curly braces.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;html! {
    &amp;lt;&amp;gt;
        &amp;lt;h2&amp;gt; {“Welcome”} &amp;lt;/h2&amp;gt;
        &amp;lt;p&amp;gt; {“This is an app made in You do Yew walkthrough”} &amp;lt;/p&amp;gt;
    &amp;lt;/&amp;gt;      
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;h2&gt;
  
  
  Router
&lt;/h2&gt;

&lt;p&gt;We want our application to render different components based on the route (Route is a string representing everything after the domain in the URL). So, for now we want to display our &lt;code&gt;Home&lt;/code&gt; component when the route is &lt;code&gt;“ / “&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Add the yew-router to the dependencies.&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;





&lt;p&gt;We need an &lt;code&gt;enum&lt;/code&gt; that contains all possible routes for the application. You can place it anywhere&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;maybe it’s best to put it in a folder called routes or similar. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here, you need to derive &lt;code&gt;Switch&lt;/code&gt; and annotate the route like presented below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;use yew_router::Switch;

use yew_router::Switch;

#[derive(Switch, Debug, Clone)]
pub enum AppRoute {
   #[to = "/"]
   Home,
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;We have defined one possible route. Now we need to handle it in the root component. We need to add some state to the &lt;code&gt;Model&lt;/code&gt; struct&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pub struct Model {
   link: ComponentLink&amp;lt;Self&amp;gt;,
   route_service: RouteService&amp;lt;()&amp;gt;,
   route: Route&amp;lt;()&amp;gt;,
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;In the create method, we can initialize the new attributes and pass them in. We create a new &lt;code&gt;RouteService&lt;/code&gt; and then we can call &lt;code&gt;get_route&lt;/code&gt; to actually get one.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let route_service : RouteService&amp;lt;()&amp;gt; = RouteService::new();
let route = route_service.get_route();

Self {
    link,
    route_service,
    route,
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;We got the current route, and it can only be &lt;code&gt;“/”&lt;/code&gt; because if you specify a route manually through URL, you’re going to get 404 Not found. When you enter the URL manually, the server looks for that file and it will never find it. You need to think of these routes as internal, and you can only change the route through the application. We will get to that soon.&lt;/p&gt;

&lt;p&gt;Now, let’s show the &lt;code&gt;Home&lt;/code&gt; component. In the &lt;code&gt;view&lt;/code&gt; method of the root component in the html! tags, we are going to add a &lt;code&gt;match&lt;/code&gt; clause. We take the value of &lt;code&gt;self.route&lt;/code&gt; and match it across all routes defined in the &lt;code&gt;AppRoute enum&lt;/code&gt;. When there’s a match, we provide the wanted component. Now you also see how to call a component, similar to HTML tags.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;html! {
    {
       match AppRoute::switch(self.route.clone()){
           Some(AppRoute::Home) =&amp;gt; html! {&amp;lt;Home/&amp;gt;},
           None =&amp;gt; html! {}
       }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;If you think about it, we get the route from &lt;code&gt;self.route&lt;/code&gt;, but how to change it from inside of other components. We will prepare it now for future use and while we are here also explain some other concepts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Message, update(), Callback, RouteAgent
&lt;/h2&gt;

&lt;p&gt;Messages are used to invoke some changes in state. They are like events. You fire an event, the component processes it, making changes to state according to the message, and rerendering if necessary. &lt;/p&gt;

&lt;p&gt;First, we need to define all possible messages in an &lt;code&gt;enum&lt;/code&gt;. The suggested practice is that the enum is called &lt;code&gt;Msg&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Create the enum in the root component. There will be only one event in the root because it only handles routing. One type of message is called &lt;code&gt;RouteChanged&lt;/code&gt; and expects a &lt;code&gt;Route&lt;/code&gt; contained in it. The message name is your choice.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pub enum Msg {
   RouteChanged(Route&amp;lt;()&amp;gt;),
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;In the &lt;code&gt;impl Component&lt;/code&gt;, we found 2 type definitions, for &lt;code&gt;Message&lt;/code&gt; and &lt;code&gt;Properties&lt;/code&gt;. Because we had none of them, we didn’t use them. Now we need to assign the type of &lt;code&gt;Message&lt;/code&gt; to &lt;code&gt;Msg&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Change this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type Message = ();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;to this.&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;





&lt;p&gt;Until now we didn’t use the &lt;code&gt;update&lt;/code&gt; method because we never made any changes to the state. We see that this method accepts a mutable reference to &lt;code&gt;self&lt;/code&gt;, meaning we can actually mutate the state, as opposed to the &lt;code&gt;view&lt;/code&gt; method, and a &lt;code&gt;Message&lt;/code&gt; of our type. It returns &lt;code&gt;ShouldRender&lt;/code&gt; which is a &lt;code&gt;bool&lt;/code&gt;. If returned &lt;code&gt;true&lt;/code&gt;, the component rerenders. Inside we &lt;code&gt;match&lt;/code&gt; the accepted &lt;code&gt;msg&lt;/code&gt; and do changes based on each &lt;code&gt;msg&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;What is happening here is that the component gets a new message &lt;code&gt;RouteChanged&lt;/code&gt;containing a &lt;code&gt;Route()&lt;/code&gt;, and then the &lt;code&gt;update&lt;/code&gt; function is called. Through the &lt;code&gt;route_service&lt;/code&gt; we set the new route and mutate the &lt;code&gt;self.route&lt;/code&gt; to point to a new (now current) route. Lastly, we return &lt;code&gt;true&lt;/code&gt; so the component renders other components based on the route.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;match msg {
    Msg::RouteChanged(route) =&amp;gt; { 
        self.route_service.set_route(&amp;amp;route.route, ());
        self.route = route
    },
}
true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;We are almost done - now what we need is a way to receive messages from the other components. Let’s add a property to the &lt;code&gt;Model&lt;/code&gt; struct:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;router_agent: Box&amp;lt;dyn Bridge&amp;lt;RouteAgent&amp;gt;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;and in the create method, also initialize the &lt;code&gt;router_agent&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let router_agent = RouteAgent::bridge(link.callback(Msg::RouteChanged));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;and of course, pass it to the &lt;code&gt;Self&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Let’s try to explain what we’ve done here. &lt;code&gt;RouteAgent&lt;/code&gt; owns a &lt;code&gt;RouteService&lt;/code&gt; so it can react when route changes from the application, or from the browser. We are using the &lt;code&gt;link&lt;/code&gt; to register a &lt;code&gt;callback&lt;/code&gt;. A callback is a function that will be called sometime in the future. That function will then fire the event (send a message) &lt;code&gt;RouteChanged&lt;/code&gt; and the component will handle it accordingly.&lt;/p&gt;

&lt;p&gt;To test this, we need another component to navigate to. Create a &lt;code&gt;TodoList&lt;/code&gt; component that displays a title. We are going to use that component to send HTTP requests later. &lt;/p&gt;

&lt;p&gt;Add a route to the AppRouter where we define all possible routes. Important note here, the matching starts at the top, so you want the most specific routes at the top and the most generic at the bottom. Usually the specific route contains the generic one in itself so if you have the generic one at the top, it will match that one even though you’re trying to navigate to some specific route.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#[to = "/lists"]
   TodoLists,
#[to = "/"]
   Home,
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;In the root component’s view method, add the new route.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Some(AppRoute::TodoLists) =&amp;gt; html! {&amp;lt;TodoList/&amp;gt;},
Some(AppRoute::Home) =&amp;gt; html! {&amp;lt;Home/&amp;gt;},
None =&amp;gt; html! {}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;Only thing left to do is create a clickable element to navigate to the &lt;code&gt;TodoList&lt;/code&gt; component. Add the &lt;code&gt;RouterAnchor&lt;/code&gt; in the Home component’s &lt;code&gt;view&lt;/code&gt; method. It changes the route so the callback in the &lt;code&gt;root&lt;/code&gt; component will execute and rerender the page.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;RouterAnchor&amp;lt;AppRoute&amp;gt; route=AppRoute::TodoLists&amp;gt;
        &amp;lt;h6&amp;gt;{"Go to my TodoList component!"}&amp;lt;/h6&amp;gt;
&amp;lt;/RouterAnchor&amp;lt;AppRoute&amp;gt;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;Done! This should now work and we are off to connecting a component to a backend with API calls.&lt;/p&gt;

&lt;h2&gt;
  
  
  HTTP Requests
&lt;/h2&gt;

&lt;p&gt;You would probably want to send HTTP requests and receive responses if you’re building a web application. Now, I have my own backend API for this application. Since it is not public, I created a simplified mock API just for this.&lt;/p&gt;

&lt;p&gt;Let’s get started. We are going to use the help of some dependencies. Add them to your &lt;code&gt;cargo.toml&lt;/code&gt;. &lt;code&gt;Serde&lt;/code&gt; and &lt;code&gt;serde_derive&lt;/code&gt; are used for (de)serialization, &lt;code&gt;yewtil&lt;/code&gt; helps us with handling HTTP requests, &lt;code&gt;anyhow&lt;/code&gt; helps with error handling.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yewtil = { git = "https://github.com/yewstack/yew", features = ["fetch"] }
serde = {version = "1.0.125", features = ["derive"]}
serde_derive = "1.0.126"
anyhow = "1.0.40"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;To the &lt;code&gt;TodoItem&lt;/code&gt; component add two more attributes. The &lt;code&gt;api&lt;/code&gt;attribute is a &lt;code&gt;Fetch&lt;/code&gt; wrapper that contains the request and the response and with that we can track the state of our API call. The &lt;code&gt;fetch_task&lt;/code&gt; is an &lt;code&gt;Option&lt;/code&gt;, as there currently may or may not be a request to fetch. We will create the &lt;code&gt;TodoList&lt;/code&gt; type later, this will hold the data from the HTTP response.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;api: Fetch&amp;lt;Request&amp;lt;Vec&amp;lt;TodoListApi&amp;gt;&amp;gt;, Vec&amp;lt;TodoListApi&amp;gt;&amp;gt;,
fetch_task: Option&amp;lt;FetchTask&amp;gt;,
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;On create, set them as &lt;code&gt;Default&lt;/code&gt; and &lt;code&gt;None&lt;/code&gt; respectively.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;api: Default::default(),
fetch_task: None,
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;This component will only be responsible for showing the data, we will have 2 possible messages. The first one is &lt;code&gt;SetApiFetchState(FetchAction)&lt;/code&gt; that will update our component’s state according to the &lt;code&gt;FetchAction&lt;/code&gt;. These can be &lt;code&gt;NotFetching&lt;/code&gt;, &lt;code&gt;Fetching&lt;/code&gt;, &lt;code&gt;Fetched&lt;/code&gt;, &lt;code&gt;Failed&lt;/code&gt;. The 2nd message is &lt;code&gt;GetApi&lt;/code&gt; and it sends the request to get data from the API.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pub enum Msg {
   SetApiFetchState(FetchAction&amp;lt;Vec&amp;lt;TodoListApi&amp;gt;&amp;gt;),
   GetApi,
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;Remember to assign the &lt;code&gt;Msg&lt;/code&gt; to type!&lt;/p&gt;

&lt;p&gt;Let’s handle the &lt;code&gt;FetchState&lt;/code&gt; first. In the update method, as always, match the &lt;code&gt;msg&lt;/code&gt;. &lt;code&gt;Fetch&lt;/code&gt; will automatically send these messages because it contains both the request and the response.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fn update(&amp;amp;mut self, msg: Self::Message) -&amp;gt; yew::ShouldRender {
       match msg {
           Msg::SetApiFetchState(fetch_state) =&amp;gt; {
               self.api.apply(fetch_state);
               true
           }
           Msg::GetApi =&amp;gt; {
           }
       }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;&lt;code&gt;Fetch&lt;/code&gt; gives us information about its state so we can render accordingly. Let’s go into the &lt;code&gt;view&lt;/code&gt; method and we can then &lt;code&gt;match&lt;/code&gt; the state and show different variations of the component.  The most important one is &lt;code&gt;Fetched(response)&lt;/code&gt;, in this one we can render all our todo lists. In the &lt;code&gt;Fetching&lt;/code&gt; state we can maybe show a loading icon, in the &lt;code&gt;Failed&lt;/code&gt;state we can show an error. This is an easy way to handle API calls, but for now we will implement only the &lt;code&gt;Fetched&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;html! {
           &amp;lt;&amp;gt;
              &amp;lt;h3&amp;gt; {"My lists"} &amp;lt;/h3&amp;gt;
              {
                 match self.api.as_ref().state() {
                    yewtil::fetch::FetchState::NotFetching(_) =&amp;gt; {
                       html! {}
                    }
                    yewtil::fetch::FetchState::Fetching(_) =&amp;gt; {
                       html! {}
                    }
                    yewtil::fetch::FetchState::Fetched(response) =&amp;gt; {
                       html! {}
                    }
                    yewtil::fetch::FetchState::Failed(_, _) =&amp;gt; {
                       html! {}
                    }
               }
          &amp;lt;/&amp;gt;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;We can’t do anything with this yet, so let’s implement the request. It would probably be good to separate this, create a new file &lt;code&gt;api.rs&lt;/code&gt;. We first need a type to deserialize into, something already used, &lt;code&gt;TodoListApi&lt;/code&gt;. It holds an &lt;code&gt;id&lt;/code&gt;, and a &lt;code&gt;title&lt;/code&gt;, both of type &lt;code&gt;String&lt;/code&gt;. You build these types according to the responses of the backend, the response from the mock api will look 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;[{"id":"1","title":"title 1"},{"id":"2","title":"title 2"},{"id":"3","title":"title 3"},{"id":"4","title":"title 4"},{"id":"5","title":"title 5"},{"id":"6","title":"title 6"},{"id":"7","title":"title 7"},{"id":"8","title":"title 8"},{"id":"9","title":"title 9"},{"id":"10","title":"title 10"}]

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

&lt;/div&gt;





&lt;p&gt;If we’re reading this response in code, it indeed is a &lt;code&gt;vector&lt;/code&gt; of &lt;code&gt;TodoListApi&lt;/code&gt; objects. Here, we can also make the code clear because building requests in the update function can be messy.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq)]
pub struct TodoListApi {
   pub id: String,
   pub title: String,
}

pub struct RequestHelper {}

static BASE_URL: &amp;amp;str = "https://60a7bb898532520017ae4d37.mockapi.io/todo_lists";

impl RequestHelper {
   pub fn get() -&amp;gt; Request&amp;lt;Nothing&amp;gt; {
       Request::get(BASE_URL)
           .body(Nothing)
           .expect("Cannot build url")
   }

   pub fn delete(body: &amp;amp;TodoListApi) -&amp;gt; Request&amp;lt;Nothing&amp;gt; {
       Request::delete(format!("{}/{}", BASE_URL, body.id))
           .body(Nothing)
           .expect("Error deleting")
   }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;This &lt;code&gt;RequestHelper&lt;/code&gt; just makes it easier to read, nothing special. Requests are &lt;code&gt;GET&lt;/code&gt; and &lt;code&gt;DELETE&lt;/code&gt;, where &lt;code&gt;GET&lt;/code&gt; will get us all of the lists, and &lt;code&gt;DELETE&lt;/code&gt; will delete one list that we provide an &lt;code&gt;id&lt;/code&gt; for.&lt;/p&gt;

&lt;p&gt;With that ready, we can implement the handler for &lt;code&gt;GetApi&lt;/code&gt; message. Switch to the update function and let’s call that API already. &lt;/p&gt;

&lt;p&gt;First, we will send a message to apply the new state - &lt;code&gt;Fetching&lt;/code&gt;. Get the request from our helper we wrote earlier and create a callback which will execute once when the response arrives. We will then try to create our &lt;code&gt;Vec&amp;lt;TodoListApi&amp;gt;&lt;/code&gt; from JSON and match that data to send the right message. &lt;/p&gt;

&lt;p&gt;Remember, I explained the callback function, it is not executed just yet. Now, using &lt;code&gt;FetchService&lt;/code&gt;, we try to fetch while providing the request and the callback we defined. We will register the task to our state.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Msg::GetApi =&amp;gt; {           
     self.link                                                                                 .send_message(Msg::SetApiFetchState(FetchAction::Fetching));

     let request = RequestHelper::get();
     let callback = self.link.callback(
        |res: Response&amp;lt;Json&amp;lt;Result&amp;lt;Vec&amp;lt;TodoListApi&amp;gt;, anyhow::Error&amp;gt;&amp;gt;&amp;gt;| {
              let Json(data) = res.into_body();
              match data {
                  Ok(d) =&amp;gt; Msg::SetApiFetchState(FetchAction::Fetched(d)),
                  Err(_) =&amp;gt; Msg::SetApiFetchState(FetchAction::NotFetching),
              }
         },
     );
     let task = FetchService::fetch(request, callback).unwrap();
     self.fetch_task = Some(task);
     true
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;Displaying the response in the view method. We want, for each of the &lt;code&gt;TodoListApi&lt;/code&gt; objects from the response, to display their &lt;code&gt;id&lt;/code&gt; and &lt;code&gt;title&lt;/code&gt; respectively.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;html! {
   &amp;lt;&amp;gt;
       &amp;lt;h3&amp;gt; {"My lists"} &amp;lt;/h3&amp;gt;
       {
          match self.api.as_ref().state() {
              yewtil::fetch::FetchState::NotFetching(_) =&amp;gt; {
                  html! {}
              }
              yewtil::fetch::FetchState::Fetching(_) =&amp;gt; {
                  html! {}
              }
              yewtil::fetch::FetchState::Fetched(response) =&amp;gt; {
                  html! {
                     response.iter().map(
                        |todo_list: &amp;amp;TodoListApi| {
                            html! {
                               &amp;lt;&amp;gt;
                           &amp;lt;h3&amp;gt;{&amp;amp;todo_list.id}{“|”} {&amp;amp;todo_list.title}&amp;lt;/h3&amp;gt;
                               &amp;lt;/&amp;gt; 
                            }                          
                        }
                     ).collect::&amp;lt;Html&amp;gt;()

                 }
              }
              yewtil::fetch::FetchState::Failed(_, _) =&amp;gt; {
                  html!{}}
              }
         }
    &amp;lt;/&amp;gt;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;h2&gt;
  
  
  Rendered
&lt;/h2&gt;

&lt;p&gt;Now, if you navigate to the TodoList component, you will not see anything because we never sent the GetApi message so the request was never sent and the response never arrived.&lt;/p&gt;

&lt;p&gt;There is a function in the component lifecycle that I haven’t mentioned - the &lt;code&gt;rendered&lt;/code&gt; function. It is called after the &lt;code&gt;view&lt;/code&gt;function is processed. It gives us a helpful &lt;code&gt;first_render&lt;/code&gt; value which we can use to, guess what, fetch the API when the component is loaded for the first time. We can do it by calling the update function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fn rendered(&amp;amp;mut self, _first_render: bool) {
       if _first_render {
           self.update(Msg::GetApi);
       }
   }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;Now it should try and fetch the data and hopefully present it to you as we described.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Properties
&lt;/h2&gt;

&lt;p&gt;Until now, we didn’t have use for them, but components can use &lt;code&gt;Properties&lt;/code&gt; to communicate. We are going to create a new component, whose purpose is to delete a list. That means every &lt;code&gt;TodoList&lt;/code&gt; component should contain a &lt;code&gt;DeleteTodoList&lt;/code&gt; component. For deleting, we want to know the &lt;code&gt;id&lt;/code&gt; of the element we are deleting, so the &lt;code&gt;DeleteTodoList&lt;/code&gt; component needs to have a binding &lt;code&gt;id&lt;/code&gt;. We can solve this problem by using properties.&lt;/p&gt;

&lt;p&gt;For starters, create a new component called &lt;code&gt;DeleteTodoList&lt;/code&gt;. Because it is also calling the API, it is similar to the &lt;code&gt;TodoList&lt;/code&gt; component. The &lt;code&gt;DELETE&lt;/code&gt; request to the API, if successful, will return that same element we are deleting. When we were getting all elements, we expected a &lt;code&gt;Vec&amp;lt;TodoList&amp;gt;&lt;/code&gt;, and now it will be a single &lt;code&gt;TodoList&lt;/code&gt;. &lt;code&gt;Msg&lt;/code&gt; is also similar, &lt;code&gt;DeleteApi&lt;/code&gt; instead of &lt;code&gt;GetApi&lt;/code&gt;, just to be clear. This component will show a button that sends the &lt;code&gt;DeleteApi&lt;/code&gt; &lt;code&gt;Msg&lt;/code&gt; when clicked on.&lt;br&gt;
&lt;br&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pub struct DeleteTodoList {
   api: Fetch&amp;lt;Request&amp;lt;TodoList&amp;gt;, TodoList&amp;gt;,
   fetch_task: Option&amp;lt;FetchTask&amp;gt;,
   link: ComponentLink&amp;lt;Self&amp;gt;,
}
pub enum Msg {
   SetApiFetchState(FetchAction&amp;lt;TodoList&amp;gt;),
   DeleteApi,
}
impl Component for DeleteTodoList {
   type Message = Msg;
   type Properties = ();

   fn create(props: Self::Properties, link: ComponentLink&amp;lt;Self&amp;gt;) -&amp;gt; Self {
       DeleteTodoListComponent {
           api: Default::default(),
           fetch_task: None,
           link,
       }
   }

   fn update(&amp;amp;mut self, msg: Self::Message) -&amp;gt; yew::ShouldRender {
   }

   fn change(&amp;amp;mut self, _props: Self::Properties) -&amp;gt; yew::ShouldRender {
       false
   }

   fn view(&amp;amp;self) -&amp;gt; yew::Html {
       match self.api.as_ref().state() {
           yewtil::fetch::FetchState::NotFetching(_) =&amp;gt; {
               html! {

                   &amp;lt;button type="button" onclick=self.link.callback(|_|     Msg::DeleteApi)&amp;gt;
                       { "Delete" }
                   &amp;lt;/button&amp;gt;
               }
           }
           yewtil::fetch::FetchState::Fetching(_) =&amp;gt; {
               html! {}
           }
           yewtil::fetch::FetchState::Fetched(_response) =&amp;gt; {
               html! {}
           }
           yewtil::fetch::FetchState::Failed(_, _) =&amp;gt; {
               html! {}
           }
       }
   }

   fn rendered(&amp;amp;mut self, _first_render: bool) {}

   fn destroy(&amp;amp;mut self) {}
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;We already created the &lt;code&gt;RequestHelper&lt;/code&gt; for deleting the element, and it takes a &lt;code&gt;TodoList&lt;/code&gt; type, but we don’t have access to it in the &lt;code&gt;DeleteTodoList&lt;/code&gt; component. We are going to use &lt;code&gt;Properties&lt;/code&gt; to forward the &lt;code&gt;TodoList&lt;/code&gt; to this component.&lt;/p&gt;

&lt;p&gt;First, we need a new type with a (suggested) name, &lt;code&gt;Props&lt;/code&gt;. &lt;code&gt;Props&lt;/code&gt; contain all types that we are sending to the child component. In this case, it will be a single &lt;code&gt;TodoList&lt;/code&gt;. Also, this struct needs to derive &lt;code&gt;Properties&lt;/code&gt; and &lt;code&gt;Clone&lt;/code&gt; traits.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#[derive(Properties, Clone)]
pub struct Props {
   pub todo_list: TodoList,
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;Add the &lt;code&gt;props&lt;/code&gt; to the &lt;code&gt;DeleteTodoList&lt;/code&gt; struct so we can access given properties and assign the type (as we did with messages) in the &lt;code&gt;impl&lt;/code&gt; &lt;code&gt;Component&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;





&lt;p&gt;The last step is to initialize the &lt;code&gt;TodoList&lt;/code&gt; struct with &lt;code&gt;props&lt;/code&gt; we got in the create method. Now we can access the props through &lt;code&gt;self.props&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We need to modify the &lt;code&gt;TodoList&lt;/code&gt; components’ view method on the &lt;code&gt;Fetched&lt;/code&gt; event, and for each &lt;code&gt;TodoList&lt;/code&gt; we get from the API, show a &lt;code&gt;DeleteTodoList&lt;/code&gt; component while passing itself. Properties are sent like HTML attributes and need to be named the same as you defined in &lt;code&gt;Props&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;MyComponent prop1=value1 prop2=value2 … /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yewtil::fetch::FetchState::Fetched(response) =&amp;gt; {
    html! {
        response.iter().map(
            |todo_list: &amp;amp;TodoList| {
                 html! {
                     &amp;lt;&amp;gt;
                        &amp;lt;h3&amp;gt;{todo_list.id}&amp;lt;/h3&amp;gt;
                        &amp;lt;h5&amp;gt;{&amp;amp;todo_list.title}&amp;lt;/h5&amp;gt;
                        &amp;lt;DeleteTodoList todo_list=todo_list.clone()/&amp;gt;
                     &amp;lt;/&amp;gt; 
                 }                          
            }
        ).collect()
   }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;Let’s try to call the API and delete one element. We need to implement the &lt;code&gt;update&lt;/code&gt; method. Basically the same as the &lt;code&gt;GetApi&lt;/code&gt; from above, but with a few tweaks. We are building the delete request passing the &lt;code&gt;todo_list&lt;/code&gt; from &lt;code&gt;props&lt;/code&gt;. That should now draw buttons for every &lt;code&gt;TodoList&lt;/code&gt;, but when clicked on, nothing happens. I mean, it does, in the background, but it does not refresh our list with this single element removed. If you reload, then it should be gone.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fn update(&amp;amp;mut self, msg: Self::Message) -&amp;gt; yew::ShouldRender {
       match msg {
           Msg::SetApiFetchState(fetch_state) =&amp;gt; {
               self.api.apply(fetch_state);
               true
           }
           Msg::DeleteApi =&amp;gt; {
               self.link.send_message(
                   Msg::SetApiFetchState(FetchAction::Fetching)
               );
               let request = RequestHelper::delete(&amp;amp;self.props.todo_list);
               let callback = self.link.callback(
                   |res: Response&amp;lt;Json&amp;lt;Result&amp;lt;TodoListApi, anyhow::Error&amp;gt;&amp;gt;&amp;gt;| {
                       let Json(data) = res.into_body();
                       match data {
                           Ok(d) =&amp;gt;                                     Msg::SetApiFetchState(FetchAction::Fetched(d)),
                           Err(_) =&amp;gt; Msg::SetApiFetchState(FetchAction::NotFetching),
                       }
                   },
               );

               let task = FetchService::fetch(request, callback).unwrap();
               self.fetch_task = Some(task);
               true
           }
       }
   }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;How do we approach this problem? We need to refresh the parent component (&lt;code&gt;TodoList&lt;/code&gt;) when &lt;code&gt;Delete&lt;/code&gt; gets executed successfully, and we do it by sending the &lt;code&gt;GetApi&lt;/code&gt; message. At this moment, we can’t. The solution I used is to create a callback function in the parent that will send the message, then forward that callback to the child through properties so we can run that callback function when the delete request is done.&lt;/p&gt;

&lt;p&gt;Go to the &lt;code&gt;TodoList&lt;/code&gt; components’ &lt;code&gt;view&lt;/code&gt; method, and there we can register a callback which will send the &lt;code&gt;GetApi&lt;/code&gt; message.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let refresh_csllbsck = self.link.callback(|_| Msg::GetApi);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;In &lt;code&gt;DeleteTodoList&lt;/code&gt;, &lt;code&gt;Props&lt;/code&gt; add the new property of type &lt;code&gt;Callback&amp;lt;Msg&amp;gt;&lt;/code&gt;, but the &lt;code&gt;Msg&lt;/code&gt; here is the &lt;code&gt;Msg&lt;/code&gt; type of the parent, so make sure you use that correctly.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pub refresh: Callback&amp;lt;super::todo_list::Msg&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;Also, we will use another message &lt;code&gt;Msg::Deleted&lt;/code&gt; to handle the refreshing of the parent component, so add that as well. Again, the &lt;code&gt;Msg&lt;/code&gt; we pass is the &lt;code&gt;Msg&lt;/code&gt; of the parent.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Deleted(super::todo_list::Msg)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;For the &lt;code&gt;update&lt;/code&gt; method, handling the &lt;code&gt;Msg::Deleted&lt;/code&gt; is as simple as it gets. We only &lt;code&gt;emit()&lt;/code&gt; the callback from our &lt;code&gt;props&lt;/code&gt;. We are returning &lt;code&gt;false&lt;/code&gt;, as we don’t need this component to refresh because the parent component is going to refresh and with that, create new child components.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Msg::Deleted(msg) =&amp;gt; {
               self.props.refresh.emit(msg);
               false
           }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;Messages are now ready, and we only need to send the &lt;code&gt;DeleteAPI&lt;/code&gt; message when the delete request is successfully executed. We have the request state handling in the &lt;code&gt;view&lt;/code&gt; method, so maybe this is where we can invoke the message &lt;code&gt;DeleteAPI&lt;/code&gt; when the state is &lt;code&gt;Fetched&lt;/code&gt;? Not really, because &lt;code&gt;view&lt;/code&gt; gets a reference to &lt;code&gt;self&lt;/code&gt; and the &lt;code&gt;update&lt;/code&gt; method needs a mutable reference to &lt;code&gt;self&lt;/code&gt; and that does not work. We also have the information about fetching state when handling the &lt;code&gt;SetApiFetchState&lt;/code&gt; message and there we can call the &lt;code&gt;update&lt;/code&gt; method. &lt;/p&gt;

&lt;p&gt;So, add the following code in the &lt;code&gt;SetApiFetchStatehandler&lt;/code&gt;. Send a &lt;code&gt;Msg::Deleted&lt;/code&gt;, but containing the right parent message, &lt;code&gt;GetApi&lt;/code&gt;. With this, when we delete an element we send a message to the parent through callback functions and make the parent reload itself.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;match fetch_state {
    FetchAction::NotFetching =&amp;gt; {}
    FetchAction::Fetching =&amp;gt; {}
    FetchAction::Fetched(_) =&amp;gt; {
           self.update(Msg::Deleted(super::todo_list::Msg::GetApi));
    }
    FetchAction::Failed(_) =&amp;gt; {}
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;Now, don’t forget to pass the callback to the child element!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;DeleteTodoList todo_list=todo_list.clone()    
refresh=refresh_callback.clone()/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;Try it out, it may look weird based on the response time, but it does work! &lt;/p&gt;

&lt;h2&gt;
  
  
  Finishing up
&lt;/h2&gt;

&lt;p&gt;You did it, you made a simple application that covers all basic concepts of Yew. Now you can try to make something out of this application, you can apply styling to make it prettier, you can expand it to do more like creating new lists, add items to list, check items as done… You could try to make your own REST API for this, rather than using mockapi.io, basically whatever comes to your mind.&lt;/p&gt;

&lt;p&gt;This was a simplified example of how everything works. You can access my application on &lt;a href="https://github.com/barrage/todo_app_rust_yew"&gt;github.com/barrage&lt;/a&gt; which uses a custom backend and more features. Check that repository for reference if you get stuck with something.&lt;/p&gt;

&lt;p&gt;If you want to learn more about Rust and Yew, or you have a project you would like to develop, don't hesitate to &lt;a href="https://www.barrage.net/contact"&gt;contact us&lt;/a&gt;.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Rust programming language: what is it &amp; how to learn it?</title>
      <dc:creator>Igor Cekelis</dc:creator>
      <pubDate>Mon, 10 May 2021 11:58:16 +0000</pubDate>
      <link>https://forem.com/barrage/rust-programming-language-what-is-it-how-to-learn-it-1867</link>
      <guid>https://forem.com/barrage/rust-programming-language-what-is-it-how-to-learn-it-1867</guid>
      <description>&lt;p&gt;Rust is a low-level systems programming language. While that might make Rust seem limited, it can be used to build many different types of applications. Rust is a tool, and tools are chosen depending on what you want to build.&lt;/p&gt;



&lt;h2&gt;
  
  
  First of all, what is Rust?
&lt;/h2&gt;

&lt;p&gt;As mentioned before, Rust is an open-source systems programming language. Rust aims to be memory-safe, thread-safe, fast, and secure. To achieve this, it introduces some new concepts, like ownership, borrowing, and lifetimes, which are the main things that keep Rust memory safe. These concepts might seem foreign if you have not seen them explicitly as you will in Rust.&lt;/p&gt;

&lt;p&gt;Thanks to these concepts, many errors in Rust are compile-time errors rather than runtime errors.&lt;/p&gt;

&lt;p&gt;Rust is a statically typed language, unlike JS, Python, Ruby, or Objective- C. As your code compiles, you will get compile type checking, and the compiler will let you know if you have any unhandled errors. Rather than re-running your application and trying to replicate an error that happened, you can spend more time writing the correct code.&lt;/p&gt;

&lt;p&gt;Let’s talk about ownership. In Rust, the compiler keeps track of which data “lives” in which scope or context. Because of this, you do not have to keep track of dangling pointers or references to parts of memory, which, if left unchecked, could leave you with segmentation faults or memory leaks.&lt;/p&gt;

&lt;p&gt;For example, in C, you have a function that returns a reference/pointer to some data. Then you call another function on that same reference, the code works, and everything seems fine, but little do you know the first pointer (returned from the function) has now been freed. This leaves you with a dangling pointer, and if you are not mindful, you could accidentally try to use that pointer again, and you will end up with some unexpected behavior.&lt;/p&gt;

&lt;p&gt;The Rust compiler keeps track of what function or what context holds what data at any given moment, so something like this most likely would not happen. At least not so easily, as the Rust compiler will let you know during compile-time that you have an error that needs to be handled.&lt;/p&gt;

&lt;p&gt;This is where ownership comes in; as mentioned before, a context or function can hold or own data, meaning the data lives in the function’s scope. Rust will not let us access that data outside of that scope unless we explicitly say so. And even then, we need to explicitly tell the compiler how we want to use that data. This is called borrowing in Rust, and that’s what makes Rust memory safe. Because all data lives in its own scope/context, once we move out of it, Rust will look at all of the data inside that scope and deallocate it.&lt;/p&gt;

&lt;p&gt;Here is an example of returning a reference to a string (&amp;amp;str) from a function and using it in another (main) function.&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fn hello_v1() -&amp;gt; &amp;amp; str{
    "Hello, world!"
}

fn main() -&amp;gt; (){
    let message = hello_v1();
    println!("{}",message);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;The example above will not work because the “Hello, world!” string is deallocated after the “hello_v1 function is finished, so we cannot print it. Also, the error we get clearly states that we are missing lifetime parameters, so let's add them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fn hello_v2&amp;lt;'a&amp;gt;() -&amp;gt; &amp;amp;'a str{
    "Hello, world!"
}

fn main() -&amp;gt; (){
    let message = hello_v2();
    println!("{}",message);
}

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

&lt;/div&gt;





&lt;p&gt;Once we change our function and add the lifetime parameters, the compiler knows that we need that string to live outside of that function, so we get the message  “Hello, world!” in our console.&lt;/p&gt;

&lt;p&gt;Rust does not have an automatic garbage collector like some other languages, Java or Python, for example.&lt;/p&gt;

&lt;p&gt;We don’t have to manually free or deallocate any memory. If we want data to live outside the function it was created in, we must tell the compiler explicitly that we do not want this data deallocated.&lt;/p&gt;

&lt;p&gt;This might seem complicated at first, but you won't even notice it once you start writing the code.&lt;/p&gt;



&lt;h3&gt;
  
  
  What is Rust used for?
&lt;/h3&gt;



&lt;p&gt;More than a few projects are created using Rust, and some of the well known are: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mozilla built its browser engine called &lt;a href="https://servo.org/"&gt;Servo&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.figma.com/blog/rust-in-production-at-figma/"&gt;Figma’s&lt;/a&gt; real-time syncing server, which is used to edit all Figma documents &lt;/li&gt;
&lt;li&gt;An open-source virtualization technology called &lt;a href="https://github.com/firecracker-microvm/firecracker"&gt;Firecracker&lt;/a&gt; is mostly being written in Rust.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.rust-lang.org/static/pdfs/Rust-npm-Whitepaper.pdf"&gt;NPM&lt;/a&gt; also uses this language to alleviate some of its CPU-bound bottlenecks.&lt;/li&gt;
&lt;/ul&gt;



&lt;h3&gt;
  
  
  Rust vs. Go
&lt;/h3&gt;

&lt;p&gt;The most obvious difference between Rust and GoLang is simplicity. Becoming productive in Go takes much less time than it does in Rust. However, simplicity comes at a cost as Go lacks some Rust features like generics and functional programming.&lt;/p&gt;

&lt;p&gt;Another difference is in memory management. Go has a garbage collector, while Rust’s memory management, as explained above, comes in the form of ownership and borrowing. While this might give an edge to Rust in performance, speed and flexibility, it can also be a setback in some cases.&lt;/p&gt;

&lt;p&gt;Concurrency in programming, simply put, is the ability to execute more than one function or task simultaneously. Go has great support for concurrency in the form of Goroutines and channels.&lt;/p&gt;

&lt;p&gt;While both of these features are also available in Rust (either using the standard library or third-party crates like Tokio), the main difference is, once again, simplicity. Writing concurrent applications in Go is easier than in Rust. Still, Rust, on the other hand, offers compile-time checking, being able to catch thread-safety bugs even before your program runs.&lt;/p&gt;

&lt;p&gt;Considering compilation time, Go blows Rust out of the water, as the Go compiler does not have to run all the optimization checks the Rust compiler does. One thing they have in common is that they both produce a static binary as an output, which means that in order to run the compiled program, you don't need an interpreter or a virtual machine. Go is very well suited to build services and simple applications. For example, a web REST API was built to replace Java and C#.&lt;/p&gt;

&lt;p&gt;Another key difference is that Go does not support macros, while Rust has a very powerful macro system. Rust is a systems programming language; therefore, it's a very good fit when you need efficiency and performance. Rust is very well suited for performance-critical applications such as web browsers, databases, operating systems, or libraries that rely on heavy mathematical calculations.&lt;/p&gt;

&lt;p&gt;This does not mean that you can’t use Rust to build a web application, as Rust has great support for building web APIs in the form of third-party crates.&lt;/p&gt;



&lt;h3&gt;
  
  
  Rust vs. C++
&lt;/h3&gt;

&lt;p&gt;Both Rust and C++ are system programming languages, which means they can write low-level code like operating systems and firmware for microcontrollers. Compared to C, both languages offer a lot of abstractions that make it possible to go high-level and write game engines and web applications.&lt;/p&gt;

&lt;p&gt;Another similarity is that neither of them uses a garbage collector to manage memory. This makes code more efficient and faster. If you have ever used C, you will know that managing memory yourself is hard and often results in undefined behaviors or segmentation faults.&lt;/p&gt;

&lt;p&gt;For this reason, C++ introduced smart pointers to mitigate some memory-related bugs. However, they are still limited in the number of guarantees they offer. Rust goes a step further and introduces the borrow checker (ownership, borrowing), preventing most of the memory safety bugs.&lt;/p&gt;

&lt;p&gt;Another selling point for Rust is its rich type system, making it possible to prevent data races at compile time. Rust introduces two traits, Sync and Send. A type is Send if it is safe to send to another thread, and a type is Sync if it is safe to share between threads. This makes sharing memory between threads possible, but the compiler will prevent you from doing so unsafely.&lt;/p&gt;

&lt;p&gt;This example shows how sharing the number between threads would be unsafe as the RefCell type is not Sync.&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fn main() {
    let mut number = std::cell::RefCell::new(2);

    let new_thread = std::thread::spawn(|| {
        let mut reference = number.borrow_mut();
        *reference = 5
    });

    let mut reference = number.borrow_mut();
    *reference = 5;

    new_thread.join();
}

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

&lt;/div&gt;





&lt;p&gt;We get this error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let new_thread = std::thread::spawn(|| {
    |                      ^^^^^^^^^^^^^^^^^^ `RefCell&amp;lt;i32&amp;gt;` cannot be shared between threads safely
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;This also highlights how great the Rust compiler is as it tells us exactly what the problem is.&lt;/p&gt;

&lt;p&gt;This is an example of how to share data between threads and changing it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fn main() {
    use std::sync::{Arc, Mutex};
   let number = Arc::new(Mutex::new(5)); // this number is in the main thread

   { 
        let number_copy = Arc::clone(&amp;amp;number);
        let new_thread = std::thread::spawn(move || { // create a new thread and pass in the num
            let mut reference = number_copy.lock().unwrap();
            *reference *= 5 // here we multiply our starting number by 5
        });
        new_thread.join().unwrap();
    }
    println!("{}",number.lock().unwrap().clone()); // now the starting number is 25

    *number.lock().unwrap() *= 5; // we multiply the starting number by 5 again

     println!("{}",number.lock().unwrap()) // here the number is 125    
}

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

&lt;/div&gt;





&lt;p&gt;Another “version” of Rust called Unsafe Rust is more similar to C++. Working in Unsafe Rust is like telling the compiler to trust you and skip some of the checks it provides. You lose the safety guarantees a safe Rust compiler gives you, but you gain the ability to interact with the low-level aspects of the operating system/hardware. Those operations are inherently unsafe. Rust’s compiler is very conservative in its checks, meaning that it prefers to check and block a few valid programs/operations rather than allow many unchecked operations. This means that even if we know that some code is safe to execute, Rust might still not allow it unless we use unsafe Rust.&lt;/p&gt;

&lt;p&gt;The areas where  Rust definitely beats C++ and many other languages are package management and documentation. The official package manager in Rust is called Cargo. Using a package is as simple as adding a line to the cargo.toml, Rust's config file. Documentation for Rust is on a whole other level compared to any other language; everything can be found at doc.rust-lang.org.&lt;/p&gt;

&lt;p&gt;Using an external library with C++ can be an issue, especially if you’re targeting multiple operating systems. There are some third-party options like Conan or Vcpkg, but they are far from being as standardized and easy to use as Cargo.&lt;/p&gt;

&lt;p&gt;Of course, the C++ ecosystem is much larger. There are many more libraries for C++, so there might not be a library for something that already exists for C++. Rust does allow for FFI (foreign function interface), which allows you to interface with C code from Rust and thus interface with C++ libraries; however, this functionality is still limited for more complex cases.&lt;/p&gt;

&lt;p&gt;Another similarity is macros. Both C++ and Rust allow them, but Rust’s macros are considered to be much more powerful and safer.&lt;/p&gt;

&lt;p&gt;Rust has two types of macros: declarative and procedural.&lt;/p&gt;

&lt;p&gt;Declarative macros are similar to ones in C++, but the key difference is that macros in Rust are hygienic in the sense that they can not interact with variables outside of their scope and cause any unwanted behavior.&lt;/p&gt;

&lt;p&gt;Procedural macros are much more powerful and complex. They act more like functions: they accept code as an input, manipulate it, and return the enriched code as an output, all at compile time.&lt;/p&gt;

&lt;p&gt;In conclusion, C++ is used far more often than Rust.  That said,  big companies like Microsoft, Google, and Apple are gradually integrating Rust with their products. C++ is not going away any time soon, thanks to its large ecosystem and legacy code built around it. Rust, however, is slowly beginning to be used as a system programming language.&lt;/p&gt;



&lt;h3&gt;
  
  
  What is the best way to learn Rust programming?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The most logical way to start learning Rust is to read the &lt;a href="https://doc.rust-lang.org/book/"&gt;Rust book&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Depending on if you already have a specific application you want to build, you might want to skip the macros section and Unsafe Rust.&lt;/li&gt;
&lt;li&gt;As always, start small. One web application I have built as a practice is a to-do list manager.&lt;/li&gt;
&lt;li&gt;There are many useful sites where you can practice, like &lt;a href="https://exercism.io/tracks/rust"&gt;exercism.io&lt;/a&gt; or &lt;a href="https://www.codewars.com/?language=rust"&gt;codewars.com&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As mentioned before, Rust has many useful third-party crates and tools; however, it already has a decent number of frameworks depending on what you want to do.  Learning about them is the path you want to take next. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rocket&lt;/strong&gt; - a web framework built on the nightly version of Rust; it's boilerplate-free, type-safe, and has a large ecosystem. It also features rich, supporting cookies, streams, built-in templating, and JSON types.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Actix&lt;/strong&gt; – a web framework also aimed to be more stable than a rocket; however, you will need to use third-party packages as it is newer and has less support.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Gotham&lt;/strong&gt; – flexible web framework built on stable Rust, statically typed, and type-safe. Supports Async operations by using the Tokio project and Hyper.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Amethyst&lt;/strong&gt; - is a game engine; it has a pool of features you might need to build a larger application. It also has better support for third party libraries.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bevy&lt;/strong&gt; - an open-source, newer, simple, data-driven game engine, heavily inspired by amethyst, supports real-time 2d rendering, 3d rendering, multiple platforms (Windows, Mac, Linux, and soon iOS and Android). Hot reload with fast compile times.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Druid&lt;/strong&gt; - an experimental, data-oriented, Rust native UI toolkit. Based on Flutter and SwiftUI. Its current development is largely driven by its use in Runebender (a new font editor).&lt;/p&gt;

</description>
      <category>rust</category>
      <category>programming</category>
      <category>backend</category>
      <category>learning</category>
    </item>
    <item>
      <title>Top 8 Sass Mixins to Speed up Your Frontend Development Process</title>
      <dc:creator>Igor Cekelis</dc:creator>
      <pubDate>Thu, 06 May 2021 12:20:20 +0000</pubDate>
      <link>https://forem.com/barrage/top-8-sass-mixins-to-speed-up-your-frontend-development-process-49ee</link>
      <guid>https://forem.com/barrage/top-8-sass-mixins-to-speed-up-your-frontend-development-process-49ee</guid>
      <description>&lt;p&gt;One of the challenges in a developer's life is speeding up and automating the development process while keeping high-quality standards. A great solution for front-end developers using SASS is its mixin capability.&lt;/p&gt;



&lt;p&gt;First of all, why is it good to use mixins, and how can it help you? &lt;/p&gt;

&lt;p&gt;You should use mixins because it lets you make groups of CSS declarations that you want to reuse through your website. &lt;/p&gt;

&lt;p&gt;Also, you can pass in values to make your mixin more flexible. Mixins are good because they make your code cleaner, and they are in the same file, so you can easily find them.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is SASS (SCSS)?
&lt;/h3&gt;

&lt;p&gt;SASS is an extension of CSS that allows you to use things like variables, nested rules, mixins, functions, etc. It makes your CSS cleaner and enables you to create style sheets faster. It is compatible with all versions of CSS. It is the most mature, stable, and powerful CSS extension in the world.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is the difference between SCSS and SASS?
&lt;/h3&gt;

&lt;p&gt;SASS is a pre-processor scripting language that compiles into CSS, while SCSS is the main syntax for the SASS, which builds on top of the existing CSS syntax.&lt;/p&gt;

&lt;h4&gt;
  
  
  SCSS example:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/* .scss file */
$background-color: #eeeeee;
$font-color: #333333;
$font-size: 24px;

/* Use the variables */
body {
     background-color: $background-color;
     color: $font-color;
     font-size: $font-size;
}

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

&lt;/div&gt;





&lt;h4&gt;
  
  
  SASS example:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/* SASS */
$background-color: #eeeeee;
$font-color: #333333;

body
     color: $font-color
     background: $background-color
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;h3&gt;
  
  
  What is mixin in SASS?
&lt;/h3&gt;

&lt;p&gt;Mixin is a directive that lets you create CSS code that is reused throughout the website. A mixin allows you to make groups of CSS declarations that you want to reuse throughout your site. You can even pass in values to make your mixin more flexible.&lt;/p&gt;

&lt;p&gt;In my opinion, mixins are the biggest feature because it allows you to write cleaner code.&lt;/p&gt;



&lt;h3&gt;
  
  
  How to use mixins?
&lt;/h3&gt;

&lt;p&gt;You have to use &lt;code&gt;@include&lt;/code&gt; followed by the name of the mixin and a semi-colon.&lt;/p&gt;



&lt;h5&gt;
  
  
  Example of usage
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;h1 {
     font-size: 14px;
     line-height: 22px;
     @include respond-above(md) {
          font-size: 18px;
          line-height: 26px;
          font-weight: 600;
     }
}

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

&lt;/div&gt;





&lt;p&gt;After compiling this SCSS code into CSS, our CSS file should look like this.&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;h1 {
     font-size: 14px;
     line-height: 22px;
     @media only screen and (min-width: 768px) {
          font-size: 18px;
          line-height: 26px;
          font-weight: 600;
     }
}

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

&lt;/div&gt;





&lt;p&gt;You can try our mixins in an &lt;a href="https://www.sassmeister.com/"&gt;online compiler&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  And, the mixins...
&lt;/h3&gt;





&lt;h4&gt;
  
  
  1.Fluid typography
&lt;/h4&gt;



&lt;p&gt;We use this mixin for responsive typography because we can avoid unnecessary media queries. It saves you a lot of time and minifies your CSS code.&lt;/p&gt;

&lt;p&gt;You don’t have to worry about line-height because we’ve extended the mixin, and it automatically calculates your line-height.&lt;br&gt;
&lt;br&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@mixin fluid-font($min-width, $max-width, $min-font-size, $max-font-size) {
  $unit1: unit($min-width);
  $unit2: unit($max-width);
  $unit3: unit($min-font-size);
  $unit4: unit($max-font-size);
  @if $unit1 == $unit2 and $unit1 == $unit3 and $unit1 == $unit4 {
    &amp;amp; {
      font-size: $min-font-size;
      line-height: $min-font-size * 1.618;
      @media screen and (min-width: $min-width) {
        font-size: calc(
          #{$min-font-size} + #{strip-unit($max-font-size - $min-font-size)} *
            ((100vw - #{$min-width}) / #{strip-unit($max-width - $min-width)})
        );
        line-height: calc(
          #{$min-font-size} + #{strip-unit($max-font-size - $min-font-size)} *
            1.618 *
            ((100vw - #{$min-width}) / #{strip-unit($max-width - $min-width)})
        );
      }
      @media screen and (min-width: $max-width) {
        font-size: $max-font-size;
        line-height: $max-font-size * 1.618;
      }
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Source: &lt;a href="https://css-tricks.com/snippets/css/fluid-typography/"&gt;CSS-Tricks&lt;/a&gt;&lt;br&gt;
&lt;br&gt;&lt;/p&gt;
&lt;h5&gt;
  
  
  Example of usage
&lt;/h5&gt;

&lt;p&gt;The first two arguments are for screen resolutions from which the font will be responsive. The last two arguments are for the smallest and largest font size.&lt;br&gt;
&lt;br&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@include fluid-font(320px, 1024px, 22px, 55px);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;h4&gt;
  
  
  2.Media queries for mobile-first design
&lt;/h4&gt;

&lt;p&gt;This mixin is a time saver and simple for writing beautiful media queries. Name your breakpoints, so they are understood by all team members. You can use pixel values, but we have some default breakpoints setup that works great.&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$breakpoints:  (
  "xs": 25em, // 400px
  "sm": 34em, // 544px
  "md": 48em, // 768px
  "lg": 60em, // 960px
  "xl": 80em, // 1280px
  "xxl": 90em // 1440px
);

@mixin respond-above($breakpoint) {
  // If the breakpoint exists in the map.
  @if map-has-key($breakpoints, $breakpoint) {
    // Get the breakpoint value.
    $breakpoint-value: map-get($breakpoints, $breakpoint);
    // Write the media query.
    @media (min-width: $breakpoint-value) {
      @content;
    }
    // If the breakpoint doesn't exist in the map.
  }
  @else {
    // Log a warning.
    @warn 'Invalid breakpoint: #{$breakpoint}.';
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  Example of usage
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;h1 {
font-size: 14px;
line-height: 22px;
@include respond-above(md) {
font-size: 18px;
line-height: 26px;
font-weight: 600;
}
}

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

&lt;/div&gt;





&lt;h4&gt;
  
  
  3. Text shortening
&lt;/h4&gt;

&lt;p&gt;Adding an ellipsis to text is not simple. But when you have this great mixin, it’s quite simple, and it can come in handy when you’re working with a lot of text, especially on small screen resolutions.&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Default line-clamp is 1
@mixin text-shorten($numLines: 1) {
  white-space: nowrap;
  text-overflow: ellipsis;
  overflow: hidden;

  @supports (-webkit-line-clamp: $numLines) {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: initial;
    display: -webkit-box;
    -webkit-line-clamp: $numLines;
    -webkit-box-orient: vertical;
  }
}

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

&lt;/div&gt;





&lt;p&gt;Source: &lt;a href="https://www.developerdrive.com/10-best-sass-mixins-for-web-developers/"&gt;DeveloperDrive&lt;/a&gt;&lt;/p&gt;

&lt;h5&gt;
  
  
  Example of usage
&lt;/h5&gt;

&lt;p&gt;If you want to add an ellipsis to text with multi-lines, you only need to pass one argument.&lt;br&gt;
&lt;br&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@include text-shorten(3);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;br&gt;&lt;br&gt;
For single line just leave it empty&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@include text-shorten();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;h4&gt;
  
  
  4.Placeholders
&lt;/h4&gt;

&lt;p&gt;Usually, the problem with placeholders is that you have to write support for all browsers. Luckily this mixin sorts it out for you.&lt;/p&gt;

&lt;p&gt;@content allows us to pass a content block into a mixin.&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@mixin placeholder {
    &amp;amp;.placeholder { @content; }
    &amp;amp;:-moz-placeholder { @content; }
    &amp;amp;::-moz-placeholder { @content; }
    &amp;amp;:-ms-input-placeholder { @content; }
    &amp;amp;::-webkit-input-placeholder { @content; }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;Source: &lt;a href="https://engageinteractive.co.uk/blog/top-10-scss-mixins"&gt;engage&lt;/a&gt;&lt;br&gt;
&lt;br&gt;&lt;/p&gt;
&lt;h5&gt;
  
  
  Example of usage
&lt;/h5&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;input, 
textarea { 
    @include input-placeholder {
        color: #333333;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  5.Flexbox Toolkit
&lt;/h4&gt;

&lt;p&gt;You should use this mixin if you are using flexbox way too much. If you have a problem knowing which one represents the main axis and which one the cross axis, this is a perfect mixin for you. It is pretty simple to use because the names are self-descriptive.&lt;br&gt;
&lt;br&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@mixin flex-column {
  display: flex;
  flex-direction: column;
}

@mixin flex-center {
  display: flex;
  align-items: center;
  justify-content: center;
}

@mixin flex-center-column {
  @include flex-center;
  flex-direction: column;
}

@mixin flex-center-vert {
  display: flex;
  align-items: center;
}

@mixin flex-center-horiz {
  display: flex;
  justify-content: center;
}

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

&lt;/div&gt;




&lt;h5&gt;
  
  
  Example of usage
&lt;/h5&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.main-container {
height: 100vh;
@include flex-center
.centered-item {
width: 100%;
max-width: 400px;
}
}

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

&lt;/div&gt;



&lt;h4&gt;
  
  
  6.Z-index
&lt;/h4&gt;

&lt;p&gt;Technically this is a pure function, not mixin. But I felt it’s worth being on the list because “z-index” is mostly misunderstood. Most developers use values like “999999”, just because they don’t really understand “z-index”.&lt;/p&gt;

&lt;p&gt;It’s so easy to lose track of z-index values when working in several different files. We started using it because everything is stored in one place and is easy to edit.&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// breakpoint var (first in array is the largest number, etc array.length)
$z-indexes: (
  "modal",
  "sidebar",
  “header”
);

@function z-index($name) {
  @if index($z-indexes, $name) {
    @return (length($z-indexes) - index($z-indexes, $name))+1;
  }
  @else {
    @warn 'There is no item "#{$name}" in this list; choose one of: #{$z-indexes}';
    @return null;
  }
}

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

&lt;/div&gt;





&lt;p&gt;Source: &lt;a href="https://engageinteractive.co.uk/blog/top-10-scss-mixins"&gt;engage&lt;/a&gt;&lt;/p&gt;



&lt;h5&gt;
  
  
  Example of usage
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.header {
z-index: z-index(‘header’);
}

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

&lt;/div&gt;





&lt;h4&gt;
  
  
  7. Position
&lt;/h4&gt;

&lt;p&gt;It is not hard to position an element with CSS, but you can save a lot of time and few lines of code. It allows you to specify the position of element and values for the four directions: top, right, bottom, left, and z-index in just one line.&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@mixin position($position: absolute, $top: null, $right: null, $bottom: null, $left: null, $z-index: initial) {
  position: $position;
  top: $top;
  right: $right;
  bottom: $bottom;
  left: $left;
  z-index: $z-index;
}

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

&lt;/div&gt;





&lt;h5&gt;
  
  
  Example of usage
&lt;/h5&gt;

&lt;p&gt;In this example we use our “z-index function”&lt;br&gt;
&lt;br&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.element-absolute {
  @include position(absolute, 60px, 0, 0, 0, z('modal'));
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;h4&gt;
  
  
  8.Responsive ratio
&lt;/h4&gt;

&lt;p&gt;The responsive ratio is not supported for all browsers. We use this to lock the aspect ratio of an element or make it fit content if it exceeds the aspect ratio's boundaries.&lt;br&gt;
&lt;br&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@mixin ratio($x,$y, $pseudo: false) {
    $padding: unquote( ( $y / $x ) * 100 + '%' );
    @if $pseudo {
        &amp;amp;:before {
            @include pseudo($pos: relative);
            width: 100%;
            padding-top: $padding;
        }
    } @else {
        padding-top: $padding;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Source: &lt;a href="https://engageinteractive.co.uk/blog/top-10-scss-mixins"&gt;engage&lt;/a&gt;&lt;/p&gt;



&lt;h5&gt;
  
  
  Example of usage
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;img {
@include ratio(16, 9);
}

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

&lt;/div&gt;





</description>
    </item>
    <item>
      <title>Step by step guide on how to set up Yubikey with GPG subkeys</title>
      <dc:creator>Igor Cekelis</dc:creator>
      <pubDate>Wed, 14 Apr 2021 14:12:06 +0000</pubDate>
      <link>https://forem.com/barrage/step-by-step-guide-on-how-to-set-up-yubikey-with-gpg-subkeys-5an8</link>
      <guid>https://forem.com/barrage/step-by-step-guide-on-how-to-set-up-yubikey-with-gpg-subkeys-5an8</guid>
      <description>&lt;p&gt;Everything around us is moving to digital. Our society is becoming more dependent upon online platforms, and it grows increasingly important that we embrace stronger online security measures.&lt;/p&gt;

&lt;p&gt;Basic two-factor authentication using 6 digits and a mobile app is not enough to keep personal and professional accounts and services secured.&lt;/p&gt;

&lt;p&gt;This method can be abused in a number of ways, like phishing attacks, third party login, and brute force.&lt;/p&gt;

&lt;p&gt;Because of this, it’s essential for professionals to add another layer of protection, incorporating hardware devices like smart cards, and YubiKey is a popular choice for it. It allows your private key to be stored and accessed only when you need it to decrypt your data.&lt;/p&gt;

&lt;p&gt;Up next is a simple and straightforward guide on generating GPG keys via your machine and transferring them to the security dongle YubiKey 4.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  What is GPG?
&lt;/h2&gt;

&lt;p&gt;GPG, or GNU Privacy Guard, is a public key cryptography implementation. This allows for the secure transmission of information between parties and can be used to verify that the origin of a message is genuine.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  What is YubiKey?
&lt;/h2&gt;

&lt;p&gt;The YubiKey is a hardware authentication device manufactured by Yubico that supports one-time passwords, public-key cryptography and authentication, and the Universal 2nd Factor and FIDO2 protocols developed by the FIDO Alliance.&lt;/p&gt;

&lt;p&gt;Now that we covered all the basics let’s get to work.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Prerequisite
&lt;/h2&gt;

&lt;p&gt;Before starting this guide, you need to download the GPG Suite.&lt;/p&gt;

&lt;p&gt;If you work on macOS, click here to download the software installer and install it. If you work on Linux, you already have it preinstalled.&lt;/p&gt;

&lt;p&gt;Also, you have to have a YubiKey!&lt;br&gt;
&lt;br&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 1 - generate Certify key
&lt;/h2&gt;

&lt;p&gt;Start key generation by running the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gpg --full-generate-key --expert
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;&lt;strong&gt;Certify key generation - step 1&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-&amp;gt; gpg --full-generate-key --expert
gpg (GnuPG) 2.2.19; Copyright (C) 2019 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Please select what kind of key you want:
   (1) RSA and RSA (default)
   (2) DSA and Elgamal
   (3) DSA (sign only)
   (4) RSA (sign only)
   (7) DSA (set your own capabilities)
   (8) RSA (set your own capabilities)
   (9) ECC and ECC
  (10) ECC (sign only)
  (11) ECC (set your own capabilities)
  (13) Existing key
  (14) Existing key from card
Your selection? 8
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Select &lt;strong&gt;8&lt;/strong&gt; ( RSA - set your own capabilities) and press enter.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;p&gt;On this prompt, it is necessary to toggle off sign capability  (&lt;strong&gt;S&lt;/strong&gt;) and encrypt capability (&lt;strong&gt;E&lt;/strong&gt;) by entering capital letter associated with it and pressing enter.&lt;/p&gt;

&lt;p&gt;When "Current allowed actions" has only "Certify", insert &lt;strong&gt;Q&lt;/strong&gt;(finished) and press enter.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Certify key generation - step 2&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Possible actions for a RSA key: Sign Certify Encrypt Authenticate Current allowed actions: Sign Certify Encrypt
    (S) Toggle the sign capability
    (E) Toggle the encrypt capability
    (A) Toggle the authenticate capability
    (Q) Finished
Your selection? s 
Possible actions for a RSA key: Sign Certify Encrypt Authenticate 
Current allowed actions: Certify Encrypt
    (S) Toggle the sign capability
    (E) Toggle the encrypt capability
    (A) Toggle the authenticate capability
    (Q) Finished Your selection? e 
Possible actions for a RSA key: Sign Certify Encrypt Authenticate Current allowed actions: Certify
    (S) Toggle the sign capability
    (E) Toggle the encrypt capability
    (A) Toggle the authenticate capability
    (Q) Finished Your selection? q
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;In the following step when prompted for key size put &lt;strong&gt;4096&lt;/strong&gt; and press enter, after that it will prompt you to input key expiration time. For this step only set it as &lt;strong&gt;0&lt;/strong&gt; (key does not expire), press enter, and then insert &lt;strong&gt;y&lt;/strong&gt; to confirm and press enter again.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;RSA keys may be between 1024 and 4096 bits long. 
What keysize do you want? (3072) 4096 
Requested keysize is 4096 bits 
Please specify how long the key should be valid.
          0 = key does not expire
       &amp;lt;n&amp;gt;  = key expires in n days
       &amp;lt;n&amp;gt;w = key expires in n weeks
       &amp;lt;n&amp;gt;m = key expires in n months
       &amp;lt;n&amp;gt;y = key expires in n years 
Key is valid for? (0) 
Key does not expire at all 
Is this correct? (y/N) y
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;Afterward, it will request your name and email address to construct a user ID to identify the key.&lt;/p&gt;

&lt;p&gt;The comment is optional. When satisfied enter &lt;strong&gt;O&lt;/strong&gt; (Okay) and press enter.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key identification&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;You need a user ID to identify your key; the software constructs the user ID from the Real Name, Comment and Email Address in this form:
     "John Doe (Some Comment) &amp;lt;john.doe@email.com&amp;gt;" 
Real name: Real Name 
E-mail address: real.name@barrage.net 
Comment: 
You selected this USER-ID:
     "Real Name &amp;lt;real.name@barrage.net&amp;gt;" 
Change (N)ame, (C)omment, (E)-mail or (O)kay/(Q)uit? o
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;&lt;strong&gt;Important&lt;/strong&gt;: Popup window requesting to set passphrase will show. (it is recommended to save passphrase in LastPass or another secure password manager)&lt;/p&gt;

&lt;p&gt;After you have set the passphrase your key has been created and you will get a message similar to one in the snipper below.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key generation - random bytes&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;We need to generate a lot of random bytes. It is a good idea to perform some other action (type on the keyboard, move the mouse, utilise the disks) during the prime generation; this gives the random number generator a better chance to gain enough entropy.
gpg: key 9CD3AF89EB04F8FF marked as ultimately trusted
gpg: directory '/home/realname/.gnupg/openpgp-revocs.d' created
gpg: revocation certificate stored as '/home/realname/.gnupg/openpgp-revocs.d/DAF272D92DAE18C1790A1E8A7C258D4980E4DCB5.rev'
public and secret key created and signed.

pub   rsa4096 2020-06-17 [C]
      DAF272D92DAE18C1790A1E8A7C258D4980E4DCB5
uid                      Real Name &amp;lt;real.name@barrage.net&amp;gt;

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

&lt;/div&gt;





&lt;p&gt;You have now generated your certification key.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 2 - create RSA sign only key
&lt;/h2&gt;



&lt;p&gt;After we have created the key for the certificate we need to add the rest of them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gpg --edit-key --expert &amp;lt;your_email_address&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(the address you provided in the previous step)&lt;/p&gt;



&lt;p&gt;&lt;strong&gt;Edit key&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gpg --edit-key --expert real.name@barrage.net   

gpg (GnuPG) 2.2.19; Copyright (C) 2019 Free Software Foundation, Inc. 
This is free software: you are free to change and redistribute it. 
There is NO WARRANTY, to the extent permitted by law. 
Secret key is available. 
gpg: checking the trustdb 
gpg: marginals needed: 3  completes needed: 1  trust model: pgp 
gpg: depth: 0  valid:   1  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 1u 
sec  rsa4096/7C258D4980E4DCB5
     created: 2020-06-17
     expires: never
     usage: C  
     trust: ultimate      validity: ultimate
[ultimate] (1). Real Name &amp;lt;real.name@barrage.net&amp;gt;

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

&lt;/div&gt;





&lt;p&gt;Insert &lt;strong&gt;addkey&lt;/strong&gt; command to start the procedure for adding the second key&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;add key - RSA sign only&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gpg&amp;gt; addkey   
Please select what kind of key you want:
    (3) DSA (sign only)
    (4) RSA (sign only)
    (5) Elgamal (encrypt only)
    (6) RSA (encrypt only)
    (7) DSA (set your own capabilities)
    (8) RSA (set your own capabilities)
   (10) ECC (sign only)
   (11) ECC (set your own capabilities)
   (12) ECC (encrypt only)
   (13) Existing key
   (14) Existing key from card 
Your selection? 4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;This step is similar to one from the creation of the first key, just on this step you choose &lt;strong&gt;4&lt;/strong&gt; ( RSA - sign only ) and press enter&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;add key - RSA sign only - length&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;RSA keys may be between 1024 and 4096 bits long. 
What keysize do you want? (3072) 4096 
Requested keysize is 4096 bits 
Please specify how long the key should be valid.
         0 = key does not expire
      &amp;lt;n&amp;gt;  = key expires in n days
      &amp;lt;n&amp;gt;w = key expires in n weeks 
      &amp;lt;n&amp;gt;m = key expires in n months 
      &amp;lt;n&amp;gt;y = key expires in n years   
Key is valid for? (0) 1y 
Key expires at Thu Jun 17 09:44:10 2021 CEST 
Is this correct? (y/N) y 
Really create? (y/N) y
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;It will again prompt you for keysize &lt;strong&gt;4096&lt;/strong&gt; and for an expiration time. This time you input &lt;strong&gt;1y&lt;/strong&gt; meaning the key will expire in 1 year. On the next two prompts confirm creation with inputting &lt;strong&gt;y&lt;/strong&gt; and pressing enter. Passphrase window will pop out requiring you to insert the passphrase which you have set up in 1st step.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3 - generate RSA encrypt only key
&lt;/h2&gt;



&lt;p&gt;This step is identical as previous (STEP 2) in every part besides selecting &lt;strong&gt;6&lt;/strong&gt; (RSA - encrypt only) on first prompt. Afterwards key length is &lt;strong&gt;4096&lt;/strong&gt;, expiration time is &lt;strong&gt;1y&lt;/strong&gt; and confirm twice with &lt;strong&gt;y&lt;/strong&gt; and passphrase on end&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;add key - RSA encrypt only&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

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

Please select what kind of key you want:
   (3) DSA (sign only)
   (4) RSA (sign only)
   (5) Elgamal (encrypt only)
   (6) RSA (encrypt only)
   (7) DSA (set your own capabilities)
   (8) RSA (set your own capabilities)
  (10) ECC (sign only)
  (11) ECC (set your own capabilities)
  (12) ECC (encrypt only)
  (13) Existing key
  (14) Existing key from card

Your selection? 6
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (3072) 4096
Requested keysize is 4096 bits
Please specify how long the key should be valid.
         0 = key does not expire
      &amp;lt;n&amp;gt;  = key expires in n days
      &amp;lt;n&amp;gt;w = key expires in n weeks
      &amp;lt;n&amp;gt;m = key expires in n months
      &amp;lt;n&amp;gt;y = key expires in n years

Key is valid for? (0) 1y
Key expires at Thu Jun 17 09:46:10 2021 CEST
Is this correct? (y/N) y
Really create? (y/N) y

We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilise the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
sec  rsa4096/7C258D4980E4DCB5
     created: 2020-06-17  expires: never       usage: C  
     trust: ultimate      validity: ultimate
ssb  rsa4096/6DCB9294B2139D96
     created: 2020-06-17  expires: 2020-06-17  usage: S  
ssb  rsa4096/40DDCC2E39087DC0
     created: 2020-06-17  expires: 2020-06-17  usage: E  
[ultimate] (1). Real Name &amp;lt;real.name@barrage.net&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;h2&gt;
  
  
  Step 4 - generate RSA authentication key
&lt;/h2&gt;



&lt;p&gt;This step is kind of combination between step 1 and step 2.&lt;/p&gt;

&lt;p&gt;Insert command &lt;strong&gt;addkey&lt;/strong&gt; and press enter, on prompt enter &lt;strong&gt;8&lt;/strong&gt; (RSA - set your own capabilities)&lt;/p&gt;

&lt;p&gt;This time current allowed actions start with: Sign and encrypt; you need to toggle them out and toggle in authenticate capability. It can be done by inputting &lt;strong&gt;S&lt;/strong&gt; to toggle out Sign capability, afterward &lt;strong&gt;E&lt;/strong&gt; to toggle out encrypt capability and finally &lt;strong&gt;A&lt;/strong&gt; to toggle in authenticate capability. When you have only Authenticate in current allowed actions input &lt;strong&gt;Q&lt;/strong&gt; and press enter.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;add key - RSA authentication&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

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

Please select what kind of key you want:
   (3) DSA (sign only)
   (4) RSA (sign only)
   (5) Elgamal (encrypt only)
   (6) RSA (encrypt only)
   (7) DSA (set your own capabilities)
   (8) RSA (set your own capabilities)
  (10) ECC (sign only)
  (11) ECC (set your own capabilities)
  (12) ECC (encrypt only)
  (13) Existing key
  (14) Existing key from card
Your selection? 8

Possible actions for a RSA key: Sign Encrypt Authenticate
Current allowed actions: Sign Encrypt
   (S) Toggle the sign capability
   (E) Toggle the encrypt capability
   (A) Toggle the authenticate capability
   (Q) Finished

Your selection? s
Possible actions for a RSA key: Sign Encrypt Authenticate
Current allowed actions: Encrypt
   (S) Toggle the sign capability
   (E) Toggle the encrypt capability
   (A) Toggle the authenticate capability
   (Q) Finished

Your selection? e
Possible actions for a RSA key: Sign Encrypt Authenticate
Current allowed actions:
   (S) Toggle the sign capability
   (E) Toggle the encrypt capability
   (A) Toggle the authenticate capability
   (Q) Finished

Your selection? a
Possible actions for a RSA key: Sign Encrypt Authenticate
Current allowed actions: Authenticate
   (S) Toggle the sign capability
   (E) Toggle the encrypt capability
   (A) Toggle the authenticate capability
   (Q) Finished

Your selection? q

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

&lt;/div&gt;





&lt;p&gt;Afterward key length will be prompted - &lt;strong&gt;4096&lt;/strong&gt; again, key expiration - &lt;strong&gt;1y&lt;/strong&gt;, confirm twice with &lt;strong&gt;y&lt;/strong&gt; and enter passphrase. If you have done everything correctly something like this should appear&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;add key - RSA authentication - length&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (3072) 4096
Requested keysize is 4096 bits
Please specify how long the key should be valid.
         0 = key does not expire
      &amp;lt;n&amp;gt;  = key expires in n days
      &amp;lt;n&amp;gt;w = key expires in n weeks
      &amp;lt;n&amp;gt;m = key expires in n months
      &amp;lt;n&amp;gt;y = key expires in n years

Key is valid for? (0) 1y
Key expires at Thu Jun 17 09:48:10 2021 CEST
Is this correct? (y/N) y
Really create? (y/N) y
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;&lt;strong&gt;add key - RSA authentication - summary&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilise the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
sec  rsa4096/7C258D4980E4DCB5
     created: 2020-06-17  expires: never       usage: C  
     trust: ultimate      validity: ultimate
ssb  rsa4096/6DCB9294B2139D96
     created: 2020-06-17  expires: 2020-06-17  usage: S  
ssb  rsa4096/40DDCC2E39087DC0
     created: 2020-06-17  expires: 2020-06-17  usage: E   
ssb  rsa4096/23BA279F2C8D06F9
     created: 2020-06-17  expires: 2020-06-17  usage: A  
[ultimate] (1). Real Name &amp;lt;real.name@barrage.net&amp;gt;

gpg&amp;gt; save

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

&lt;/div&gt;





&lt;p&gt;Last but not least, enter command &lt;strong&gt;save&lt;/strong&gt; to finish your key creation process.&lt;/p&gt;



&lt;h2&gt;
  
  
  Step 5 - create backups
&lt;/h2&gt;

&lt;p&gt;Run following commands to export keys&lt;/p&gt;

&lt;p&gt;Provide passphrase where necessary.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;create backups - commands&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gpg --export-ownertrust &amp;gt; ~/.gnupg/backup_trustdb.txt
gpg --armor --export-secret-keys &amp;lt;your_email_address&amp;gt; &amp;gt; ~/.gnupg/secret_keys_&amp;lt;your_email_address&amp;gt;.asc
###(enter passphrase if prompted)
gpg --armor --export-secret-subkeys &amp;lt;your_email_address&amp;gt; &amp;gt; ~/.gnupg/secret_subkeys_&amp;lt;your_email_address&amp;gt;.asc 
###(enter passphrase if prompted)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;you can list keys with&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;list keys&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ls -all ~/.gnupg/openpgp-revocs.d
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;h2&gt;
  
  
  Step 6 - transport keys to yubikey
&lt;/h2&gt;

&lt;p&gt;Insert yubikey into usb slot in your machine and write command&lt;br&gt;
&lt;/p&gt;

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

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

&lt;/div&gt;





&lt;p&gt;to get data from your Yubikey. If it works it should provide with Yubikey related data.&lt;/p&gt;

&lt;p&gt;Enter command&lt;br&gt;
&lt;/p&gt;

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

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

&lt;/div&gt;





&lt;p&gt;to be able to edit card data. Type command&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;





&lt;p&gt;and it will prompt you administrator pin.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Important: Default admin pin is 12345678.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You can use command&lt;br&gt;
&lt;/p&gt;

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

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

&lt;/div&gt;





&lt;p&gt;to view all possible commands for your Yubikey.&lt;/p&gt;

&lt;p&gt;When you are done you can type command&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;





&lt;p&gt;To insert keys into your yubikey run following commands and it will output like from the screen below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gpg --edit-key --expert &amp;lt;your_email_address&amp;gt;

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

&lt;/div&gt;





&lt;p&gt;&lt;strong&gt;Exporting keys to yubikey - list keys&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gpg --edit-key --expert john.doe@barrage.net

gpg (GnuPG) 2.2.19; Copyright (C) 2019 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Secret key is available.

sec  rsa4096/7C258D4980E4DCB5
     created: 2020-06-17  expires: never       usage: C  
     trust: ultimate      validity: ultimate
ssb  rsa4096/6DCB9294B2139D96
     created: 2020-06-17  expires: 2020-06-17  usage: S  
ssb  rsa4096/40DDCC2E39087DC0
     created: 2020-06-17  expires: 2020-06-17  usage: E   
ssb  rsa4096/23BA279F2C8D06F9
     created: 2020-06-17  expires: 2020-06-17  usage: A  
[ultimate] (1). Real Name &amp;lt;real.name@barrage.net&amp;gt;

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

&lt;/div&gt;





&lt;p&gt;To add the key you need to select it and transfer to Yubikey. If for example we typekey1 it will select 1st key and put * next to its ssb (like on picture below). Typing key 1 again will deselect that key&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;add key to yubikey - key 1&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ssb* rsa4096/2C66AD4A15960BDB
     created: 2020-06-16  expires: 2021-06-16  usage: S
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;h2&gt;
  
  
  Add 1st key (signature key)
&lt;/h2&gt;



&lt;p&gt;Select 1st key with command: &lt;strong&gt;key 1&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Write command: &lt;strong&gt;keytocard&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When it prompts where to store, type : &lt;strong&gt;1&lt;/strong&gt; (Signature key)&lt;/p&gt;

&lt;p&gt;enter passphrase&lt;/p&gt;

&lt;p&gt;enter admin pin&lt;br&gt;
&lt;br&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Add 2nd key (encryption key)
&lt;/h2&gt;



&lt;p&gt;Deselect 1st key with command: &lt;strong&gt;key 1&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Select 2nd key with command: &lt;strong&gt;key 2&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Write command: &lt;strong&gt;keytocard&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;where to store: &lt;strong&gt;2&lt;/strong&gt; (encryption)&lt;/p&gt;

&lt;p&gt;enter passphrase&lt;/p&gt;

&lt;p&gt;enter admin pin&lt;br&gt;
&lt;br&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Add 3rd key (authentication key)
&lt;/h2&gt;

&lt;p&gt;Deselect 2nd key with command: &lt;strong&gt;key 2&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Select 3rd key with command: &lt;strong&gt;key 3&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Write command: &lt;strong&gt;keytocard&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;where to store: &lt;strong&gt;3&lt;/strong&gt; (authentication)&lt;/p&gt;

&lt;p&gt;enter passphrase&lt;/p&gt;

&lt;p&gt;enter admin pin&lt;/p&gt;

&lt;p&gt;Deselect 3rd key: &lt;strong&gt;key 3&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Write command: &lt;strong&gt;save&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gpg -k (list public keys)

gpg -K (list private keys)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;&lt;strong&gt;Important&lt;/strong&gt; - You must change password and admin password on Yubikey for obvious security reasons&lt;/p&gt;

&lt;p&gt;Enter edit mode with command: &lt;strong&gt;gpg --card-edit&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Enter command: &lt;strong&gt;admin&lt;/strong&gt; to allow admin commands&lt;/p&gt;

&lt;p&gt;Enter command: &lt;strong&gt;passwd&lt;/strong&gt; and following will be shown&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1 - change PIN
2 - unblock PIN
3 - change Admin PIN
4 - set the Reset Code
Q - quit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;Select &lt;strong&gt;1&lt;/strong&gt; to change PIN&lt;/p&gt;

&lt;p&gt;enter current pin (default: 123456) &lt;br&gt;
enter new pin&lt;br&gt;
confirm new pin&lt;br&gt;
After you have finished PIN change it will give you the password menu again;&lt;/p&gt;

&lt;p&gt;Select &lt;strong&gt;3&lt;/strong&gt; to change Admin PIN &lt;/p&gt;

&lt;p&gt;enter current admin pin (default: 12345678)&lt;br&gt;
enter new pin&lt;br&gt;
confirm new pin&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Important&lt;/strong&gt;: Save PIN, ADMIN PIN and PASSPHRASE to LastPass and protect access to them with LastPass master password&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 7 - associate GPG with gitLab
&lt;/h2&gt;


&lt;h2&gt;
  
  
  Add GPG key in your gitlab settings
&lt;/h2&gt;

&lt;p&gt;Export public key to clipboard with following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gpg --armor --export &amp;lt;your_email_address&amp;gt;  | pbcopy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;After that go to your gitlab site, click on your user button and click on settings in dropdown menu&lt;/p&gt;



&lt;p&gt;Go to the GPG Keys section in the menu, paste your public key from clipboard into text area, press add keys and the result should look like this&lt;/p&gt;

&lt;h2&gt;
  
  
  Associate GPG key on your local machine to GIT repository
&lt;/h2&gt;

&lt;p&gt;List your secret keys with following command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gpg --list-secret-keys --keyid-format LONG &amp;lt;your_email_address&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;&lt;strong&gt;List secret keys&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sec   rsa4096/7C258D4980E4DCB5 2020-06-17 [C]
      DAF272D92DAE18C1790A1E8A7C258D4980E4DCB5
uid                 [ultimate] Real Name &amp;lt;real.name@barrage.net&amp;gt;
ssb  rsa4096/6DCB9294B2139D96 2020-06-17 [S] [expires: 2021-06-17]
ssb  rsa4096/40DDCC2E39087DC0 2020-06-17 [E] [expires: 2021-06-17]
ssb  rsa4096/23BA279F2C8D06F9 2020-06-17 [A] [expires: 2021-06-17]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;copy GPG key id that starts with ssb and has S next to date.&lt;/p&gt;

&lt;p&gt;in this example → &lt;strong&gt;6DCB9294B2139D96&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Run the following commands to edit your local git configuration.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git config --global user.signingkey 6DCB9294B2139D96
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git config --global gpg.program gpg
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git config --global commit.gpgsign true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





</description>
      <category>yubikey</category>
      <category>gpg</category>
      <category>mfa</category>
      <category>2fa</category>
    </item>
    <item>
      <title>What is a phishing attack and how to identify it - the definite guide</title>
      <dc:creator>Igor Cekelis</dc:creator>
      <pubDate>Wed, 14 Apr 2021 13:21:14 +0000</pubDate>
      <link>https://forem.com/barrage/what-is-a-phishing-attack-and-how-to-identify-it-the-definite-guide-21bn</link>
      <guid>https://forem.com/barrage/what-is-a-phishing-attack-and-how-to-identify-it-the-definite-guide-21bn</guid>
      <description>&lt;p&gt;We know everyone has heard of them, but not everyone can easily detect that they are under phishing cyber attack. In this article, we will lay out the basics that will help you spot the malicious email in your Inbox. &lt;/p&gt;

&lt;p&gt;We will also explain the difference between phishing and spear phishing attacks and how to identify them.&lt;/p&gt;



&lt;p&gt;Email remains widely used in both business and private matters as one of the leading communication methods. Because of that, email is commonly used as a marketing platform, and we are all familiar with all kinds of promotional newsletters ending up in our mailboxes.&lt;/p&gt;

&lt;p&gt;That led to the inevitable production of malicious acts, frauds, spam emails, and some more sophisticated ways of malicious intents.&lt;/p&gt;



&lt;h2&gt;
  
  
  Spam
&lt;/h2&gt;

&lt;p&gt;Let’s talk about spam for a moment. Spam can be anything unwanted, but it’s mostly used as a term for unwanted emails, direct messages (IM), or mobile (SMS) messages. Spam emails are mainly based on (Sosa, 2010):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Money loan frauds&lt;/li&gt;
&lt;li&gt;“Make money fast” frauds&lt;/li&gt;
&lt;li&gt;Pharmaceutical marketing&lt;/li&gt;
&lt;li&gt;Chain mail&lt;/li&gt;
&lt;li&gt;Illegal pirated software etc.&lt;/li&gt;
&lt;/ul&gt;



&lt;p&gt;About 40% of emails are considered spam, and some sources say that the number has increased up to 70%. (Awad, Elsuofi, 2011).&lt;/p&gt;



&lt;p&gt;What is not considered spam?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your friend emailing you with funny cat videos multiple times a day (your friend is a known entity to you)&lt;/li&gt;
&lt;li&gt;Your boss sending you an unexpected employee termination letter (certainly unwanted, but not spam)&lt;/li&gt;
&lt;li&gt;Emails containing malicious software like viruses (they have some common points, but they are not considered spam)&lt;/li&gt;
&lt;/ul&gt;



&lt;p&gt;How to identify spam email?&lt;/p&gt;

&lt;p&gt;Except for the topics mentioned above, spam emails often have the following characteristics:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The sender is unknown or suspicious&lt;/li&gt;
&lt;li&gt;It has spelling errors, often seemingly unintentional, with the goal of tricking your spam filter&lt;/li&gt;
&lt;li&gt;The author is claiming that the email isn't spam&lt;/li&gt;
&lt;li&gt;Offers are on a large discount, but just for you or for a short and limited period (asking to perform some urgent action)&lt;/li&gt;
&lt;li&gt;You are gifted with an award, mostly financial&lt;/li&gt;
&lt;/ul&gt;



&lt;h2&gt;
  
  
  Phishing
&lt;/h2&gt;



&lt;p&gt;Phishing is an attack vector where the attacker is sending a malicious email (because of which that email can be classified as spam) where he is falsely identifying himself as someone reliable and known (e.g., your bank, your boss, Google, Facebook, etc.) with the intention of stealing sensitive data like passwords, credit card numbers, PINs, etc. Phishing emails evolved and became more sophisticated and persuasive, thus more dangerous. (Basnet, Mukkamala, Sung, 2008).&lt;/p&gt;

&lt;p&gt;There are multiple features that can be string indicators by which we can recognize phishing attempts in emails:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Email is sent over a new domain - the domain is activated a few hours or days ago&lt;/li&gt;
&lt;li&gt;Multiple domains in the URL - phishing emails often ask you to visit an attached URL. Sometimes that particular URL can have multiple domains, which is a case of a URL Redirection Attack. (e.g., &lt;a href="http://www.example.com/login.php?redirect=http://www.bla.com/home.php"&gt;http://www.example.com/login.php?redirect=http://www.bla.com/home.php&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;The occurrence of an IP address in a URL - legitimate websites usually have their own domain.&lt;/li&gt;
&lt;li&gt;The occurrence of shortened URLs (Bitly, TinyURL)&lt;/li&gt;
&lt;li&gt;Mismatch of email from the email header and the email body&lt;/li&gt;
&lt;/ul&gt;



&lt;p&gt;Phishing emails often claim that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;There are problems with your account&lt;/li&gt;
&lt;li&gt;You must confirm some personal info&lt;/li&gt;
&lt;li&gt;You must perform some kind of urgent action&lt;/li&gt;
&lt;li&gt;You should check the attachment&lt;/li&gt;
&lt;/ul&gt;



&lt;p&gt;Recently, we had a nicely realized phishing attempt. It can be seen in Figure 1. The body of the email contains a persuasive message about some security concerns related to the used software. The email is sent from a domain that includes the real name of the product (ledgersupport.io), but in fact, isn’t sent by the real source, meaning the attacker is falsely identifying themselves to the victim.&lt;/p&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--atmNMV----/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.prismic.io/barrage/f176cd4e-2a7c-4015-bdfb-00e6972ddb4d_ledger-phishing-attack-attempt.png%3Fauto%3Dcompress%2Cformat" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--atmNMV----/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.prismic.io/barrage/f176cd4e-2a7c-4015-bdfb-00e6972ddb4d_ledger-phishing-attack-attempt.png%3Fauto%3Dcompress%2Cformat" alt="alt text"&gt;&lt;/a&gt;&lt;/p&gt;
 Ledger phishing attempt 





&lt;h2&gt;
  
  
  What is a spear phishing attack?
&lt;/h2&gt;



&lt;p&gt;Spear phishing is an advanced and more sophisticated attack vector because the attacker is targeting a specific individual, organization, or company. The attacker presents himself as a trustworthy source or a specific individual well known to the victim. Spear phishing attacks that are targeting high-level executives like CEOs are called whaling attacks. Executives in companies and organizations are often targeted because they are usually under pressure and doing time-critical tasks. Those attacks are often asking to abuse processes, deliver some sensitive information, or perform urgent payments. (Northcutt)&lt;/p&gt;

&lt;p&gt;How do spear phishing attacks work?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Attacker researches his victims and all info about them (email, full name, native language, job position)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Once the data is collected, the attacker works out a strategy. Usually, this includes duplicating  web pages that the victim is familiar with and  creating a fake email address&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The attacker sends a fake email message that looks like it came from the trusted person/institution. More sophisticated attacks are happening over several emails, where attackers gradually build trust, story, and context&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Attack usually ends with the victim sending valuable information&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;



&lt;p&gt;In some even more sophisticated scenarios, the attacker can go a step further and spoof the email address to make it look more trustworthy to the reader. Email spoofing is the act of sending emails with false sender addresses (Malwarebytes, 2020).&lt;/p&gt;

&lt;p&gt;A great example of email spoofing can be seen in Figure 2, where the attacker pretends to be the USA president.&lt;/p&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6ijTBSH1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.prismic.io/barrage/42ba1560-d414-439e-b572-382a4ad40e99_email-spoofing.png%3Fauto%3Dcompress%2Cformat" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6ijTBSH1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.prismic.io/barrage/42ba1560-d414-439e-b572-382a4ad40e99_email-spoofing.png%3Fauto%3Dcompress%2Cformat" alt="alt text"&gt;&lt;/a&gt;&lt;/p&gt;
 An example of email spoofing 





&lt;p&gt;By checking the headers of that particular email, it can be seen that the sender is obviously not the real president, as shown in Figure 3. Long story short, the “From” and “Return-Path” fields don’t match, which is a solid indication that this email is spoofed.&lt;/p&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--YreIsEUN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.prismic.io/barrage/943dfe56-f4b6-4560-9bc0-914291803385_spear-phishing-attempt.jpg%3Fauto%3Dcompress%2Cformat" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YreIsEUN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.prismic.io/barrage/943dfe56-f4b6-4560-9bc0-914291803385_spear-phishing-attempt.jpg%3Fauto%3Dcompress%2Cformat" alt="alt text"&gt;&lt;/a&gt;&lt;/p&gt;
 Email headers of phishing attempt examples 





&lt;p&gt;Let’s go back to Spear Phishing. A few days ago, we had a “textbook example” of a spear phishing attempt that can be seen in Figure 4. The attacker presented himself as someone known to the victim, and the victim can easily overlook the email address he has created. The content of the email asks for a big payment that is due today. It has almost every characteristic of a classic spear phishing attempt.&lt;/p&gt;

&lt;p&gt;Translation of the text in Figure 4:&lt;/p&gt;

&lt;p&gt;Subject: Payment&lt;/p&gt;

&lt;p&gt;Body: Good morning, can we pay 26.650 Euros today? I need advice. Thank you. Best regards&lt;/p&gt;



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

&lt;p&gt;We can conclude that the difference between spam and phishing is in the malicious intent of the attacker. The main goal of the spammer is to sell something, often-low quality products. Spammers just have an item to sell and choose spam as their preferred technique for contacting potential buyers. It is important to emphasize that their items and products can also be fraudulent. Phishing attempts have a malicious nature, and their goal is mostly stealing information, data, credentials, or money. (Belcic, 2020)&lt;/p&gt;

&lt;p&gt;In the "phishing vs. spear phishing" case, we can say that the difference between phishing and spear fishing is the approach and the target. Spear phishing attacks target specifically chosen individuals, organizations, or companies, whereas phishing attacks have a wider spread vector and are sent to multiple (hundreds, thousands) of potential victims. Because of that, spear phishing attacks are way more dangerous because they seem personal, and attackers present themselves as a known or trusted individual or party.&lt;/p&gt;

&lt;p&gt;Be wary and careful when dealing with any email you receive, expected or not. Do not hesitate; ask someone to help and analyze a particular email for you. Always take your time to double-check when asked to perform something that might be unusual or suspicious in any way. If you suspect that a particular email is malicious, approach it with caution, and never attempt to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click on any URLs&lt;/li&gt;
&lt;li&gt;Click on any form buttons&lt;/li&gt;
&lt;li&gt;Open any attachments, no matter the extension&lt;/li&gt;
&lt;li&gt;Provide personal, confidential, or credit card information&lt;/li&gt;
&lt;li&gt;Provide passwords&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And always:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Report suspicious emails to the security team&lt;/li&gt;
&lt;li&gt;Keep your anti-virus, anti-spam, etc., up to date&lt;/li&gt;
&lt;li&gt;Check the headers of an email for mismatches of the sender email&lt;/li&gt;
&lt;li&gt;Outlook how-to: &lt;a href="https://answers.microsoft.com/en-us/msoffice/forum/msoffice_outlook-msoffice_custom-mso_2010/view-source-of-an-email/1d5029bd-9401-4342-8409-fa396b8959fb"&gt;https://answers.microsoft.com/en-us/msoffice/forum/msoffice_outlook-msoffice_custom-mso_2010/view-source-of-an-email/1d5029bd-9401-4342-8409-fa396b8959fb&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Thunderbird how-to: CTRL+U&lt;/li&gt;
&lt;li&gt;Gmail how-to: &lt;a href="https://support.google.com/mail/answer/29436?hl=en"&gt;https://support.google.com/mail/answer/29436?hl=en&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you think that you’ve opened a malicious URL or attachment:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Disconnect your device from the internet and any networks to reduce the potential spread of the malware&lt;/li&gt;
&lt;li&gt;Perform a complete scan of your system&lt;/li&gt;
&lt;li&gt;Contact your financial institution or bank in case your financial information is at risk&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Keep in mind that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Phishing and spear phishing attacks are very easy to perform&lt;/li&gt;
&lt;li&gt;No technical/hacking knowledge is needed to perform these types of attacks&lt;/li&gt;
&lt;li&gt;It is easy to obtain tools and scripts to perform phishing attempts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The best way to avoid phishing and other email related scams is to raise security awareness and educate yourself and learn about the phishers' tactics. There is a lot of great literature online about the topics mentioned above. Feel free to contact us anytime if you wish to learn something more about the following topic.&lt;/p&gt;

</description>
      <category>phishing</category>
      <category>spearphishing</category>
      <category>spam</category>
      <category>security</category>
    </item>
  </channel>
</rss>
