<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Mark Michon</title>
    <description>The latest articles on DEV Community by Mark Michon (@markmichon).</description>
    <link>https://dev.to/markmichon</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%2F280359%2F9e63002e-5577-4152-ba7c-a9f6aac878ca.jpeg</url>
      <title>DEV Community: Mark Michon</title>
      <link>https://dev.to/markmichon</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/markmichon"/>
    <language>en</language>
    <item>
      <title>Six security risks of user input in ruby code</title>
      <dc:creator>Mark Michon</dc:creator>
      <pubDate>Mon, 10 Apr 2023 23:02:18 +0000</pubDate>
      <link>https://dev.to/bearer/six-security-risk-of-user-input-in-ruby-code-4c9a</link>
      <guid>https://dev.to/bearer/six-security-risk-of-user-input-in-ruby-code-4c9a</guid>
      <description>&lt;p&gt;We all know that user input should be treated extra cautiously. Any input field, GET request, or API endpoint is a risky entry point. With that in mind, here's a rundown of some of some especially dangerous ways you'll want to avoid using user input.&lt;/p&gt;

&lt;h2&gt;
  
  
  Unsafe deserialization
&lt;/h2&gt;

&lt;p&gt;Deserializing untrusted data can be pretty sketch. Attackers can transfer payloads or malicious code disguised as serialized data, which you'll in turn unfurl. This can take the shape of image uploads for profile pics, specialized file formats, and more. Protect required formats like image uploads by validating them, and don't use any output from them in things like error messages.&lt;/p&gt;

&lt;p&gt;In other instances, avoid it if you can. That wouldn't be much of a tip though, so if you have to consume serialized data, use a data-only and language-agnostic format like JSON—or XML if you must. These formats lessen the chance of any custom logic existing in the data. You can learn more in the &lt;a href="https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html"&gt;OWASP cheatsheet&lt;/a&gt; on the subject.&lt;/p&gt;

&lt;h2&gt;
  
  
  Don't use Eval or system with user input
&lt;/h2&gt;

&lt;p&gt;Eval might not come up often, but if it does you definitely don't want to use it on anything supplied by a user. Since eval will build new ruby code based on strings, attackers can use it to &lt;/p&gt;

&lt;p&gt;Ruby's &lt;code&gt;system&lt;/code&gt;, &lt;code&gt;exec&lt;/code&gt;, &lt;code&gt;spawn&lt;/code&gt;, and &lt;code&gt;command&lt;/code&gt; are equally dangerous if the user input it making up the whole or partial command. Fortunately, &lt;a href="https://guides.rubyonrails.org/security.html#command-line-injection"&gt;as advised by the Rails docs&lt;/a&gt;, you can use &lt;code&gt;system&lt;/code&gt; with a second argument to safely pass parameters. For example &lt;code&gt;system(command, parameters&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Don't assemble paths or URLs
&lt;/h2&gt;

&lt;p&gt;There are many instances where taking user selections or input, and forming a URL or path may be beneficial. Search is the most common instance, but you may also use it for uploading images, adding links, redirecting pages, etc.&lt;/p&gt;

&lt;p&gt;Generally, you'll want to avoid directly building paths based on user input. The most common reason is to avoid forms of &lt;a href="https://owasp.org/Top10/A10_2021-Server-Side_Request_Forgery_%28SSRF%29/"&gt;server-side request forgery&lt;/a&gt;. This type of attack can expose details about your own services, or be used to trick users into thinking a redirected path is coming from your application instead of the attacker's.&lt;/p&gt;

&lt;p&gt;You can instead restrict selections to a subset of safe options, and then use those options to build the URL.&lt;/p&gt;

&lt;p&gt;In instances where you can't possibly know all the safe values, you can match safe patterns—such as a list of approved domains for URL forwarding or file sources. The same goes for file types. When in doubt, it's better to be overly conservative when restricting the type of user input you use to build URLs or file paths.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sessions
&lt;/h2&gt;

&lt;p&gt;It's useful to start by making sure your sessions use a database as a backend rather than cookie based session storage.&lt;/p&gt;

&lt;p&gt;In addition, you should avoid allowing user input as the session key. You want a system that has no outside influence, even though all session data sent from the client to the server should be considered untrusted. This allows you to properly validate session keys and IDs without the variability of any user-defined values.&lt;/p&gt;

&lt;h2&gt;
  
  
  unsanitized renders
&lt;/h2&gt;

&lt;p&gt;With all the focus on sanitizing user input, it can be easy to neglect sanitizing renders. Ideally the user input shouldn't make it this far, but an additional step will prevent any mistakes on the receiving end.&lt;/p&gt;

&lt;p&gt;If you're using &lt;code&gt;render html&lt;/code&gt; you can wrap items in &lt;code&gt;strip_tags&lt;/code&gt; to ensure code isn't generated in the HTML output. This helps prevent cross-site scripting (XSS) attacks in which content is injected into your page.&lt;/p&gt;

&lt;p&gt;If you're using an external view engine, or a javascript framework like react in addition to your ruby backend, you can rely on similar sanitization methods like the &lt;a href="https://github.com/cure53/DOMPurify"&gt;DOMPurify&lt;/a&gt; library.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stop runaway regex
&lt;/h2&gt;

&lt;p&gt;We think of regular expressions as a common means of validating input, but some may find it valuable to allow users to build their own conditions. Allowing user input use in a regular expression isn't dangerous on it's own, but it can cause an issue when the regular expression requires excessive CPU resources. &lt;/p&gt;

&lt;p&gt;To prevent this, specify a timeout when working with regular expressions—particularly those that rely on use input.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Regexp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/a|b/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;timeout: &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will help in stoping regular expression denial of service (ReDoS) attacks. &lt;/p&gt;

&lt;h2&gt;
  
  
  Keeping up with top ruby security tips
&lt;/h2&gt;

&lt;p&gt;It can be challenging to keep up with security best practices. In addition to watching for vulnerability reports, you can also run regular scans on your codebase with a SAST tool like Bearer CLI. It's a free and secure way to get practical security feedback on your ruby code. Check it out on GitHub at &lt;a href="https://github.com/Bearer/bearer/"&gt;bearer/bearer&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>security</category>
    </item>
    <item>
      <title>Let’s scan DEV’s forem project with Bearer and analyze the results</title>
      <dc:creator>Mark Michon</dc:creator>
      <pubDate>Wed, 29 Mar 2023 18:13:59 +0000</pubDate>
      <link>https://dev.to/bearer/lets-scan-devs-forem-project-with-bearer-and-analyze-the-results-1g9b</link>
      <guid>https://dev.to/bearer/lets-scan-devs-forem-project-with-bearer-and-analyze-the-results-1g9b</guid>
      <description>&lt;p&gt;Using open-source tools to test open-source projects feels like a great match. It wasn't until the other day that I remembered that the team behind &lt;a href="https://dev.to"&gt;DEV&lt;/a&gt; had open-sourced the bones of the site as &lt;a href="https://github.com/forem/forem" rel="noopener noreferrer"&gt;Forem&lt;/a&gt;. To make it an even better match, the stack matches up nicely with the currently supported languages included in Bearer's new &lt;a href="https://github.com/Bearer/bearer" rel="noopener noreferrer"&gt;free and open-source security application security testing (SAST) tool&lt;/a&gt;. Unlike many security tools, this one is really focused on helping devs make sense of security concerns in an actionable way.&lt;/p&gt;

&lt;p&gt;In this article, we'll install the &lt;a href="https://github.com/bearer/bearer/" rel="noopener noreferrer"&gt;Bearer CLI&lt;/a&gt;, run it against forem, and analyze the results to see what issues arise and how we might tackle them. &lt;em&gt;Spoiler alert: we'll find a bunch of results—some easy to fix, some we can ignore, and some that might be larger judgment calls.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Install bearer
&lt;/h2&gt;

&lt;p&gt;If you'd like to follow along, follow the install and scan instructions. Otherwise, you can skip down to the &lt;a href="https://www.notion.so/Let-s-scan-DEV-s-forem-project-with-Bearer-and-analyze-the-results-1a115315c66f4d5ab70efed7c425fb1a" rel="noopener noreferrer"&gt;analyze the results&lt;/a&gt; section below.&lt;/p&gt;

&lt;p&gt;The quickest way to install Bearer is with homebrew or curl.&lt;/p&gt;

&lt;p&gt;Homebrew:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew &lt;span class="nb"&gt;install &lt;/span&gt;Bearer/tap/bearer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Curl:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-sfL&lt;/span&gt; https://raw.githubusercontent.com/Bearer/bearer/main/contrib/install.sh | sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can then confirm that everything is installed and working by running the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bearer version
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see the version number and sha value. At the time of this writing, the version is 1.1.0.&lt;/p&gt;

&lt;h2&gt;
  
  
  Clone forem and run a security scan
&lt;/h2&gt;

&lt;p&gt;If you haven't already, go ahead and clone forem locally.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/forem/forem.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's a pretty big project, so it might take a few minutes. Once complete, navigate into the project—likely with &lt;code&gt;cd forem&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We'll start by running Bearer with all of its default settings. This will give us a text-based security report.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bearer scan &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Note: The &lt;code&gt;.&lt;/code&gt; in the line above just means "run this command on the current directory".&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Depending on your machine, this could take a few minutes. For reference, the scan took 1m26s for me, with the rule analysis taking another 1s.&lt;/p&gt;

&lt;p&gt;When the scan completes, you'll see the security report.&lt;/p&gt;

&lt;h2&gt;
  
  
  Analyzing the results
&lt;/h2&gt;

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

&lt;p&gt;Here's a &lt;a href="https://gist.github.com/markmichon/5129e0cdac1888f506586f7e9c95ced1" rel="noopener noreferrer"&gt;gist with the full output&lt;/a&gt;. The scan detected 0 critical failures, 44 high failures, 2 medium failures, and 36 warnings. That's 82 items that have the potential for improvement.&lt;/p&gt;

&lt;p&gt;These failures and warnings are from Bearer's built-in &lt;a href="https://docs.bearer.com/reference/rules/" rel="noopener noreferrer"&gt;rules&lt;/a&gt;. Rules are checks against best practices. Most are derived from the &lt;a href="https://owasp.org/Top10/" rel="noopener noreferrer"&gt;OWASP Top 10&lt;/a&gt; and the &lt;a href="https://cwe.mitre.org/index.html" rel="noopener noreferrer"&gt;CWE&lt;/a&gt;, and some are common best practices for languages and frameworks. At the time of this scan, there were 107 default rules.&lt;/p&gt;

&lt;p&gt;Back to the results, 46 failures and 36 warnings seem like a lot, but if we break down the results we can manage them more easily. For one, let's ignore the warnings for now.&lt;/p&gt;

&lt;p&gt;You can tell the scan to only show certain severity levels:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bearer scan &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;--severity&lt;/span&gt; critical,high,medium
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Don't worry, the scan itself is cached, so this won't take the full amount of time again.&lt;/p&gt;

&lt;p&gt;Of the 46 remaining failures, we can start to see that there are only a handful of rules that make up these failures. This is because Bearer shows you each location within your code where the failure occurred. These rules are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Javascript: open redirect&lt;/li&gt;
&lt;li&gt;React: dangerouslySetInnerHTML&lt;/li&gt;
&lt;li&gt;Assorted ruby user input rules&lt;/li&gt;
&lt;li&gt;Ruby: weak encryption&lt;/li&gt;
&lt;li&gt;Ruby: data sent to Honeybadger&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Remediating the failures
&lt;/h2&gt;

&lt;p&gt;With our nice to-do list in place, let's start at the highest severity level—in this case, there were no critical items so we'll start at "high".&lt;/p&gt;

&lt;h3&gt;
  
  
  Javascript: open redirect
&lt;/h3&gt;

&lt;p&gt;This rule, &lt;code&gt;javascript_lang_open_redirect&lt;/code&gt;,  is one I actually hadn't heard of before. If we look at the &lt;a href="https://docs.bearer.com/reference/rules/javascript_lang_open_redirect/" rel="noopener noreferrer"&gt;docs link&lt;/a&gt; provided in the output, we have some advice on fixing the problem and a handful of resources. We can see this relates to OWASP A01:2021 and CWE-601. If we review the OWASP open redirect guidance, it basically says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Unvalidated redirects and forwards are possible when a web application accepts untrusted input that could cause the web application to redirect the request to a URL contained within untrusted input. By modifying untrusted URL input to a malicious site, an attacker may successfully launch a phishing scam and steal user credentials.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Still a bit unsure? Let’s look at the file and line output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HIGH: Open redirect detected. [CWE-601]
https://docs.bearer.com/reference/rules/javascript_lang_open_redirect
To skip this rule, use the flag --skip-rule=javascript_lang_open_redirect

File: app/javascript/runtimeBanner/RuntimeBanner.jsx:63

 63     window.location.href = targetLink;

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

&lt;/div&gt;



&lt;p&gt;Looking at the &lt;code&gt;RuntimeBanner&lt;/code&gt; component and heading down to line 63, we can then make a judgment on whether this should change. In this case, if we go a bit earlier, we'll see this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...
const urlParams = new URLSearchParams(window.location.search);
const targetPath = urlParams.get('deep_link');
if (currentOS() === 'iOS') {
// The install now must target Apple's AppStore
installNowButton.href = FOREM_APP_STORE_URL;
// We try to deep link directly by launching a custom scheme and populate
// the retry button in case the user will need it
const targetLink = `${APP_LAUNCH_SCHEME}://${window.location.host}${targetPath}`;

retryButton.href = targetLink;

window.location.href = targetLink;
...

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

&lt;/div&gt;



&lt;p&gt;I don't know enough about their codebase to make a valid judgment here. It may be safe since it's only used for appstore links, but it also accepts get params as input for the redirect—which you normally want to avoid without properly validating them. Have a thought? Leave a comment below.&lt;/p&gt;

&lt;h3&gt;
  
  
  React: dangerouslySetInnerHTML
&lt;/h3&gt;

&lt;p&gt;If you've done any React work, you know all about &lt;code&gt;dangerouslySetInnerHTML&lt;/code&gt;. It's a necessary evil sometimes, but there is in fact a way to make it safer. That's why the rule &lt;code&gt;javascript_react_dangerously_set_inner_html&lt;/code&gt; exists. Checking the &lt;a href="https://docs.bearer.com/reference/rules/javascript_react_dangerously_set_inner_html" rel="noopener noreferrer"&gt;doc link&lt;/a&gt;, we see the following advice:&lt;/p&gt;

&lt;p&gt;Sanitize data when using dangerouslySetInnerHTML&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;dangerouslySetInnerHTML&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;__html&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;sanitize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;  &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Along with a &lt;a href="https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html" rel="noopener noreferrer"&gt;link to OWASP's advice&lt;/a&gt; for further context. Great! We can include the DOMPurify library and it’s an easy fix.&lt;/p&gt;

&lt;h3&gt;
  
  
  Assorted ruby user input rules
&lt;/h3&gt;

&lt;p&gt;I'm grouping many of the triggered ruby rules together here because they all have one thing in common: avoid doing things directly with user input. The following rules trigger in various places throughout the code:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ruby_lang_http_url_using_user_input&lt;/li&gt;
&lt;li&gt;ruby_lang_reflection_using_user_input&lt;/li&gt;
&lt;li&gt;ruby_rails_redirect_to&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;While different in their implementation, they all share the same risk and can more or less be resolved in the same way. If we look at the remediation docs for ruby_lang_reflection_using_user_input, the advice is to compare the input to pre-set values, then pass those values to the method instead of directly passing the input. Like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;method_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:action&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="s2"&gt;"option1"&lt;/span&gt;
        &lt;span class="s2"&gt;"method1"&lt;/span&gt;
    &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="s2"&gt;"option2"&lt;/span&gt;
        &lt;span class="s2"&gt;"method2"&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="nb"&gt;method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;method_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;There may be some cases where the scan picks up perfectly safe redirects and reflections due to the nature of params, so it’s good to evaluate these incidents on a case-by-base basis.&lt;/p&gt;

&lt;h3&gt;
  
  
  Ruby: weak encryption
&lt;/h3&gt;

&lt;p&gt;The weak encryption rule, &lt;code&gt;ruby_lang_weak_encryption&lt;/code&gt;, is one of my personal favorites. Many of us come to assume that most encryption libraries and algorithms are good enough, but it turns out that many of the old standards are showing their age. &lt;a href="https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/09-Testing_for_Weak_Cryptography/04-Testing_for_Weak_Encryption" rel="noopener noreferrer"&gt;OWASP identifies&lt;/a&gt; algorithms it considers weak, so let's avoid using them to encrypt sensitive data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;MEDIUM: Weak encryption library usage detected. [CWE-331, CWE-326]
https://docs.bearer.com/reference/rules/ruby_lang_weak_encryption
To skip this rule, use the flag --skip-rule=ruby_lang_weak_encryption

File: app/services/mailchimp/bot.rb:153

 153       Digest::MD5.hexdigest(email.downcase)

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

&lt;/div&gt;



&lt;p&gt;In this case, it looks like the mailchimp service is only using MD5 to encrypt email addresses. We can replace it with something like &lt;a href="https://dev.to/sylviapap/bcrypt-explained-4k5c"&gt;BCrypt&lt;/a&gt; instead.&lt;/p&gt;

&lt;h3&gt;
  
  
  Ruby: data sent to Honeybadger
&lt;/h3&gt;

&lt;p&gt;Finally, the last rule to trigger on forem's code, &lt;code&gt;ruby_third_parties_honeybadger&lt;/code&gt;, is the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;MEDIUM: Sensitive data sent to Honeybadger detected. [CWE-201]
https://docs.bearer.com/reference/rules/ruby_third_parties_honeybadger
To skip this rule, use the flag --skip-rule=ruby_third_parties_honeybadger

File: app/controllers/omniauth_callbacks_controller.rb:77

76 Honeybadger.context({
77 username: @user.username,
78 user_id: @user.id,
79 auth_data: request.env["omniauth.auth"],
80 auth_error: request.env["omniauth.error"].inspect,
...
82 })

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

&lt;/div&gt;



&lt;p&gt;You may wonder why this is a problem. In the case of this code, we're sending the user's &lt;code&gt;username&lt;/code&gt; to a third-party service. While username isn't inherently sensitive data, it certainly has to potential to be and should be treated as such. It's better to use IDs that can't identify the user if the third party—in this case, &lt;a href="https://www.honeybadger.io/" rel="noopener noreferrer"&gt;honeybadger&lt;/a&gt;—is breached. You can see the full list of &lt;a href="https://docs.bearer.com/reference/datatypes/" rel="noopener noreferrer"&gt;supported data types&lt;/a&gt;, sorted by category, on the docs.&lt;/p&gt;

&lt;h2&gt;
  
  
  What else can we do
&lt;/h2&gt;

&lt;p&gt;On top of all the rules mentioned so far, there were also a handful of warnings—mostly around setting application-wide security. This is good advice, but depending on the use case might not be as vital. The great thing is, you can customize the scan to your needs by adjusting the flags, and even add comments to your code—much like you would with a linter—to ignore parts that are intentional choices. You can even &lt;a href="https://docs.bearer.com/guides/custom-rule/" rel="noopener noreferrer"&gt;write your own custom rules&lt;/a&gt; to check for any code patterns or security best practices that aren't included in the default ruleset.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://docs.bearer.com/explanations/reports/" rel="noopener noreferrer"&gt;SAST security report&lt;/a&gt; is the core of the Bearer CLI app, but there are also privacy reports, secret detection, and a deeper dataflow report. You can even &lt;a href="https://docs.bearer.com/guides/github-action/" rel="noopener noreferrer"&gt;run it as a GitHub action&lt;/a&gt; each time new code gets pushed. &lt;a href="https://github.com/Bearer/bearer" rel="noopener noreferrer"&gt;Give it a try&lt;/a&gt; on your own apps, improve the code on some of your favorite open-source projects, and help make it better. &lt;/p&gt;

&lt;p&gt;Let me know in the comments what other guides you'd like to see on using the CLI. And, if you work on forem, let us know if we can improve the results!&lt;/p&gt;

</description>
      <category>security</category>
      <category>tooling</category>
    </item>
    <item>
      <title>How to scan your ruby or JS project for security improvements, for free.</title>
      <dc:creator>Mark Michon</dc:creator>
      <pubDate>Tue, 28 Mar 2023 00:35:22 +0000</pubDate>
      <link>https://dev.to/bearer/how-to-scan-your-ruby-or-js-project-for-security-improvements-for-free-1dh1</link>
      <guid>https://dev.to/bearer/how-to-scan-your-ruby-or-js-project-for-security-improvements-for-free-1dh1</guid>
      <description>&lt;p&gt;Security tools are intimidating. They’re made for security teams that already know the jargon and the details like CWE identifiers. But what about developers? We have tools that check for vulnerable dependencies and tools that check for leaked secrets, but we’re missing easy—actionable—advice on making our code more secure.&lt;/p&gt;

&lt;p&gt;Good news! There’s a free open-source tool that can scan your code, check for known risks, and give you a list of things that need fixing. All are sorted by how risky the code is—based on things like how sensitive the data is and how damaging a breach or leak would be. It’s called &lt;a href="https://github.com/Bearer/bearer"&gt;Bearer&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here's why it's pretty rad:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Quick scans: most projects take under a minute, with big ones like forem, gitlab, etc taking between 3 and 10 minutes.&lt;/li&gt;
&lt;li&gt;Your data never leaves your computer. The open source scanner reads your code, but doesn't send it or metadata to any servers.&lt;/li&gt;
&lt;li&gt;Practical advice: Each triggered rule shows you where in your code the problem is, and links out to documentation on how to improve it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;TLDR: The workflow ends up looking like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;bearer&lt;/span&gt; &lt;span class="nb"&gt;scan&lt;/span&gt; &lt;span class="sr"&gt;/your-project
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can run that locally, or as part of CI/CD, and each time you’ll receive a summarized report. Let’s get into it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installing Bearer
&lt;/h2&gt;

&lt;p&gt;There is a full list of ways to &lt;a href="https://docs.bearer.com/reference/installation/"&gt;install Bearer&lt;/a&gt; in the docs, but the most common are using Brew or curl.&lt;/p&gt;

&lt;p&gt;Homebrew:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew &lt;span class="nb"&gt;install &lt;/span&gt;Bearer/tap/bearer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Curl:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-sfL&lt;/span&gt; https://raw.githubusercontent.com/Bearer/bearer/main/contrib/install.sh | sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Run your first scan
&lt;/h2&gt;

&lt;p&gt;Now navigate to the project you’d like to scan, and run the &lt;code&gt;scan&lt;/code&gt; command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bearer scan &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The app scans your project in a few stages. It starts by detecting and classifying sensitive data types, then feeds that data into whichever report type you use. The default is the Security report, which shows all the security risks found in your codebase by checking against a set of “Rules”.&lt;/p&gt;

&lt;p&gt;You get a summary that looks a bit 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;107 checks, 12 failures, 6 warnings

CRITICAL: 0
HIGH: 1 (CWE-798)
MEDIUM: 11 (CWE-201, CWE-209, CWE-313, CWE-315, CWE-319, CWE-326, CWE-331, CWE-532, CWE-539)
LOW: 0
WARNING: 6 (CWE-312)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Plus each failure and warning shows you where it happened and has a link to docs on how to fix the problem.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;MEDIUM: Sensitive data in a JWT detected. [CWE-315]
https://docs.bearer.com/reference/rules/ruby_lang_jwt
To skip this rule, use the flag --skip-rule=ruby_lang_jwt

File: lib/jwt.rb:6

 3     JWT.encode(
 4       {
 5         id: user.id,
 6         email: user.email,
 7         class: user.class,
 8       },
 9       nil,
    ...
 11     )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These rules come from the &lt;a href="https://owasp.org/www-project-top-ten/"&gt;OWASP top 10&lt;/a&gt;, popular CWEs, and some general best practices from the appsec community. It’s a quick way to get a second pair of eyes on your code—especially if you aren’t a security expert.&lt;/p&gt;

&lt;h2&gt;
  
  
  Check it out
&lt;/h2&gt;

&lt;p&gt;It's a big ask to put something in your pipeline or test flow, but I really love just using it as a one-off scan as I'm building something new. Kind of like linting, but for security. Right now the main security scan supports ruby and JS/TS codebases. Give it a try—you can &lt;a href="https://github.com/Bearer/bear-publishing"&gt;use our test repo&lt;/a&gt; if you like. Let us know what you think and if there's something you'd like to see added &lt;a href="https://github.com/Bearer/bearer/issues/new/choose"&gt;open an issue&lt;/a&gt; on GitHub.&lt;/p&gt;

</description>
      <category>security</category>
      <category>appsec</category>
      <category>tooling</category>
    </item>
    <item>
      <title>Measuring Performance in Node.js with Performance Hooks</title>
      <dc:creator>Mark Michon</dc:creator>
      <pubDate>Fri, 11 Dec 2020 15:21:09 +0000</pubDate>
      <link>https://dev.to/bearer/measuring-performance-in-node-js-with-performance-hooks-585p</link>
      <guid>https://dev.to/bearer/measuring-performance-in-node-js-with-performance-hooks-585p</guid>
      <description>&lt;p&gt;&lt;em&gt;📣 This post originally appeared as &lt;a href="https://blog.bearer.sh/an-introduction-to-node-performance-measurement-apis/"&gt;Measuring Performance in Node.js with Performance Hooks&lt;/a&gt; on &lt;a href="https://blog.bearer.sh"&gt;The Bearer Blog&lt;/a&gt;.&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;Measuring performance in Node.js applications can sometimes be a challenge. Due to the nature of the &lt;a href="https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/"&gt;event loop&lt;/a&gt; and asynchronous code, determining the actual time a piece of code takes to execute requires tools built into the platform. First added in Node.js v8.5, as stableas of v12, the Performance Measurement APIs are stable and allow much more accurate monitoring than earlier implementations. In this article we'll look at the basics of Node.js performance hooks and how to use them to time the execution of functions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why are Performance Measurement APIs important?
&lt;/h2&gt;

&lt;p&gt;Sometimes called Perf Hooks, in part because they are imported from &lt;code&gt;perf_hooks&lt;/code&gt; in Node applications, these APIs allow developers to set various markers that make measuring the run-time of an application easier. &lt;a href="https://nodejs.org/dist/latest-v14.x/docs/api/perf_hooks.html"&gt;Node's implementation&lt;/a&gt; is an adaptation of the &lt;a href="https://w3c.github.io/perf-timing-primer/"&gt;W3C's Web Performance APIs&lt;/a&gt;, but with changes that make more sense for Node apps rather than browser javascript.&lt;/p&gt;

&lt;p&gt;With these APIs, you can measure the time it takes individual dependencies to load, how long your app takes to initially start, and even how long individual web service API calls take. This allows you to make more informed decisions on the efficiency of specific algorithms, the effects of API choices on application performance, and establish baselines for "normal" operation to help identify anomalies when they happen.&lt;/p&gt;

&lt;p&gt;In the past, this may have been done using &lt;code&gt;Date.now()&lt;/code&gt; and some basic operations to find the duration. There are some flaws in this technique, as occasionally you can end up with a zero value or negative numbers. A slightly more accurate approach is to use &lt;code&gt;process.hrtime()&lt;/code&gt;, but it still has limitations and needs to be manually set everywhere you end to use it.&lt;/p&gt;

&lt;p&gt;To better understand how these newer APIs work, let's look at an example.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using perf hooks
&lt;/h2&gt;

&lt;p&gt;Imagine we have an asynchronous function called &lt;code&gt;someAction&lt;/code&gt;, and we want to know how long it takes to run.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;someAction&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To track it's performance, first we need to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Import the &lt;code&gt;perf_hooks&lt;/code&gt; module from Node.js&lt;/li&gt;
&lt;li&gt; Establish and observer to watch for performance events&lt;/li&gt;
&lt;li&gt; Initialize the observer&lt;/li&gt;
&lt;li&gt; Mark the appropriate areas with start/stop markers, and measure the difference.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let's start by importing the module and setting up the observer—steps 1-3.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;performance&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;PerformanceObserver&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;perf_hooks&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;perfObserver&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;PerformanceObserver&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getEntries&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="nx"&gt;perfObserver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;observe&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;entryTypes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;measure&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="na"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The observer code can look intimidating at first if you haven't used a similar API (like IntersectionObserver, for instance). In the code above we establish a new &lt;code&gt;PerformanceObserver&lt;/code&gt; and pass it a callback function. Each time one of our performance events fires (more on that shortly), the entry is added to a list of Performance Entries (&lt;code&gt;items&lt;/code&gt;). &lt;code&gt;items.getEntries()&lt;/code&gt; is a bit of work that needs to happen to get the entries into an iterable format, which we then loop over with &lt;code&gt;forEach&lt;/code&gt; and isolate each entry into the &lt;code&gt;entry&lt;/code&gt; argument in the callback function.&lt;/p&gt;

&lt;p&gt;Finally, &lt;code&gt;perfObserver.observe&lt;/code&gt; tells our new observer what to look for and how to act. In this case, we want to watch for &lt;code&gt;measure&lt;/code&gt; events (more on this shortly), and we set the buffer to &lt;code&gt;true&lt;/code&gt;. This buffer setting just means that the observer will wait until all events are finished before running the &lt;code&gt;PerformanceObserver&lt;/code&gt; callback. If it were set to false, &lt;code&gt;items&lt;/code&gt; would always have a single entry and the callback would run every time a matching &lt;code&gt;entryType&lt;/code&gt; occurred.&lt;/p&gt;

&lt;p&gt;This boilerplate handles our setup, so let's actually measure the example function we spoke of earlier.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ...setup code from previous example&lt;/span&gt;

&lt;span class="nx"&gt;performance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mark&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;example-start&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;someAction&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nx"&gt;performance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mark&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;example-end&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;performance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;measure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;example&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;example-start&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;example-end&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the code above, we are using &lt;code&gt;performance.mark&lt;/code&gt; and &lt;code&gt;performance.measure&lt;/code&gt;. The &lt;code&gt;mark&lt;/code&gt; method is used to place a performance timestamp in our code. The name can be anything, but using some form of start/end or similar suffix can help avoid user error. The &lt;code&gt;measure&lt;/code&gt; method takes three arguments. A label for the measurement, the starting marker, and the ending marker.&lt;/p&gt;

&lt;p&gt;With this done, our observer from earlier will pick up the &lt;code&gt;measure&lt;/code&gt; type, add it to the callback argument, and when our code finishes we'll see the entry logged to the console. It will look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;PerformanceEntry &lt;span class="o"&gt;{&lt;/span&gt;
    name: &lt;span class="s2"&gt;"example"&lt;/span&gt;,
    entryType: &lt;span class="s2"&gt;"measure"&lt;/span&gt;,
    startTime: 3869.689664,
    duration: 122.123131
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;startTime&lt;/code&gt; can be useful for organizing the data in logs, but we mostly care about &lt;code&gt;duration&lt;/code&gt; as it indicates how long the operation took.&lt;/p&gt;

&lt;h2&gt;
  
  
  Monitoring function performance
&lt;/h2&gt;

&lt;p&gt;In our last example, we set markers for the start and end of a code snippet. We did this in part because our function was asynchronous, and we were using the &lt;code&gt;await&lt;/code&gt; keyword. If you're measuring the performance of a synchronous function, there is a helper available to handle the markers for you. Instead of setting a start and end with &lt;code&gt;performance.mark&lt;/code&gt;, you can wrap the function in &lt;code&gt;performance.timerify&lt;/code&gt; and change the observe code to watch for function entries.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ...perfObserver = new PerformanceObserver...&lt;/span&gt;
&lt;span class="c1"&gt;// ...&lt;/span&gt;

&lt;span class="nx"&gt;perfObserver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;observe&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;entryTypes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;function&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;perfWrapper&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;performance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;timerify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;syncFunction&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;perfWrapper&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By changing the &lt;code&gt;entryTypes&lt;/code&gt; to &lt;code&gt;function&lt;/code&gt; and wrapping the synchronous function in &lt;code&gt;timerify&lt;/code&gt;, we can avoid the need to set start and end marks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Practical application for API calls
&lt;/h2&gt;

&lt;p&gt;Let's imagine a scenario where we have calls to third-party APIs and we want to keep track of how long each call takes. We can use this data to create a baseline, track performance, etc.&lt;/p&gt;

&lt;p&gt;Using the technique from our first example, we can start logging the performance. Here's what that looks like with the full setup code, and the addition of an external call using the &lt;code&gt;Axios&lt;/code&gt; library.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;performance&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;PerformanceObserver&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;perf_hooks&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;axios&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;axios&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;customLogger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;our-custom-logging-solution&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;perfObserver&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;PerformanceObserver&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getEntries&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;customLogger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// fake call to our custom logging solution&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="nx"&gt;perfObserver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;observe&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;entryTypes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;measure&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="na"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;


&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;performance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mark&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;swapi-start&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;axios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://swapi.dev/api/people/1/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;finally&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;performance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mark&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;swapi-end&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;performance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;measure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://swapi.dev/api/people/1/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;swapi-start&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;swapi-end&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In a scenario like this, we can imagine a codebase that manipulates and formats the performance data, and sends it off in batches to a monitoring tool or logging solution. Then, over time, establishes the normal behavior of an API in order to detect when anomalies occur—kind of like what &lt;a href="https://www.bearer.sh"&gt;Bearer&lt;/a&gt; does.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using performance measurement to your advantage
&lt;/h2&gt;

&lt;p&gt;Measuring and parsing the individual performance of all API calls can be cumbersome. That's part of the reason we built a tool at Bearer to monitor APIs using techniques similar to those mentioned here, along with the extra niceties of a full SaaS solution.&lt;/p&gt;

&lt;p&gt;A similar addition to Node.js to keep an eye on is the &lt;a href="https://nodejs.org/dist/latest-v14.x/docs/api/async_hooks.html"&gt;Async Hooks API&lt;/a&gt;. It's still experimental, but can allow you to apply the features of the performance measurements API to asynchronous functions more easily. There's still room for improvement in our examples above and in similar methods. We also need to take into account any lag or pauses in the event loop.&lt;/p&gt;

&lt;p&gt;We'll dive into async hooks and ways to use the performance monitoring API to monitor event loop lag in the future so subscribe for updates on &lt;a href="https://blog.bearer.sh"&gt;The Bearer Blog&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>node</category>
      <category>performance</category>
      <category>api</category>
    </item>
    <item>
      <title>The Importance of Request Timeouts</title>
      <dc:creator>Mark Michon</dc:creator>
      <pubDate>Mon, 30 Nov 2020 16:27:48 +0000</pubDate>
      <link>https://dev.to/bearer/the-importance-of-request-timeouts-l3n</link>
      <guid>https://dev.to/bearer/the-importance-of-request-timeouts-l3n</guid>
      <description>&lt;p&gt;&lt;em&gt;📣 This post originally appeared as &lt;a href="https://blog.bearer.sh/http-request-timeouts/" rel="noopener noreferrer"&gt;The Importance of Request Timeouts&lt;/a&gt; on &lt;a href="https://blog.bearer.sh" rel="noopener noreferrer"&gt;The Bearer Blog&lt;/a&gt;.&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;Networks are unreliable. Third-party dependencies, like APIs, are unreliable. This is why we build resiliency into our applications and services. Most prep work is focused around HTTP requests, but an aspect of them that is often overlooked is &lt;strong&gt;timeouts&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are timeouts?
&lt;/h2&gt;

&lt;p&gt;Timeouts set a max wait time on a request. We can think about timeouts in two contexts: the client and the server. Client timeouts set a limit on how long they are willing to wait for a response to come back—and in some cases be completed. Server timeouts set a limit on how long the connection should remain open. For example, if a client is taking an exceptionally long time to receive a response, the server may choose to close the connection. Be careful not to limit your thinking of client as browser and server as backend. The client is the application making the request.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.bearer.sh%2Fcontent%2Fimages%2F2020%2F09%2Fjson-2.svg" 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%2Fblog.bearer.sh%2Fcontent%2Fimages%2F2020%2F09%2Fjson-2.svg" alt="json-2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can also consider timeouts to be split into three types: a connect timeout, a write timeout, and a read timeout. Connect timeouts affect how long the client will wait for a connection to establish. Write timeouts affect how long the connection will wait while the client tries to send data, like a &lt;code&gt;POST&lt;/code&gt; request. Read timeouts cover the amount of time it takes to actually receive the response back from the server. Some HTTP clients allow you to set each separately, and other's only allow you to set a total combined value.&lt;/p&gt;

&lt;p&gt;Timeouts are all about "waiting." When your application makes a request, it has to wait for the response. Even in asynchronous code, eventually that action needs to be handled and processed. Without a timeout established, your code relies on the assumption that it will either receive a successful response or an error. In reality, this isn't always the case. As we said at the start, networks are unreliable. If the request is delayed along the way, and never receives an official error response, your application will hang indefinitely. This is why timeouts are important. &lt;strong&gt;They stop the indefinite hang scenario&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Libraries can't be trusted
&lt;/h2&gt;

&lt;p&gt;We make assumptions about "battle-tested" libraries and packages. Their heavy use adds clout, but sometimes the "good default" for a large audience isn't always the best default for your needs. For a few examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://requests.readthedocs.io/en/master/" rel="noopener noreferrer"&gt;Requests&lt;/a&gt;, the leading Python library for making HTTP requests, does not have a default value for timeouts. &lt;a href="https://requests.readthedocs.io/en/latest/user/advanced/#timeouts" rel="noopener noreferrer"&gt;They encourage you to set timeout values&lt;/a&gt;, but if you forget or assume a sensible default exists, your code will be susceptible to hanging connections.&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://golang.org/pkg/net/http/" rel="noopener noreferrer"&gt;Go's net/http module&lt;/a&gt; also has no default timeout. You can, and should, set your own timeout value.&lt;/li&gt;
&lt;li&gt;  The default browser implementations lack default timeouts, and in some cases lack easy ways to add timeouts. Both XHR and Fetch have issues, but most packages on NPM do incorporate ways to set timeouts. &lt;a href="https://www.npmjs.com/package/axios" rel="noopener noreferrer"&gt;Axios&lt;/a&gt;, for example has a default of 0, which it interprets as infinite.&lt;/li&gt;
&lt;li&gt;  Ruby's net/http has 60s defaults for all timeout types. This is pretty high for most use cases, but is at least a default value.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As we can see, even if you're using the language's built-in request module or one of the most popular packages available, you will likely hit problems with insufficient timeouts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Choosing a timeout value
&lt;/h2&gt;

&lt;p&gt;Determining your ideal timeout involves many variables. Connection timeouts should be kept short, while read and write timeouts are more dependant on the needs of the service. There are some considerations to make when determining the ideal timeout duration for each API call.&lt;/p&gt;

&lt;p&gt;One way is to monitor the response time from the APIs you connect to using a tool like &lt;a href="https://www.bearer.sh" rel="noopener noreferrer"&gt;Bearer&lt;/a&gt;. This works well for helping estimate the average time a successful request takes, and how long a &lt;em&gt;successful error&lt;/em&gt; takes. Another approach is to focus on the user experience. If a request is connected to the UI—directly or otherwise—your timeouts should be tied to how long you're willing to delay the interaction. For background-style tasks, higher timeouts are appropriate. For more immediate tasks, shorter timeouts are a better option. Combined with optimistic updates and a retry strategy, timeouts can directly improve your application's UX.&lt;/p&gt;

&lt;p&gt;Another variable to consider is serverless functions. If your code is making a request from a serverless endpoint, make sure the timeout is no greater than the max invocation time of the function. The function's max invocation time is often a hard limit. Combined with a little buffer for the time it takes the request and response to move between your application and the remote server, these values can better inform your timeout value. For example: &lt;code&gt;timeout = maxInvocationTime + averageResponseTime&lt;/code&gt;, where the average response time is the time it normally takes. This isn't a perfect formula, but it's a great place to start.&lt;/p&gt;

&lt;p&gt;Finally, don't punish users for their connection speeds. This primarily applies to browsers, but a user on a 3G connection may require a significantly longer timeout when uploading an image than a user on a faster connection. Keep this in mind for any user-facing connections.&lt;/p&gt;

&lt;h2&gt;
  
  
  So what should you do?
&lt;/h2&gt;

&lt;p&gt;Ideally, set specific timeouts for each API call your application makes. Use the needs of the interaction, or your services, to determine what the maximum timeout should be. If you're using an HTTP library or module that doesn't surface an easy configuration for this, consider switching to one that does.&lt;/p&gt;

&lt;p&gt;Setting custom timeouts for every request can be tedious, especially when you don't have the data necessary to make an informed decision. One alternative approach is to use a solution like Bearer's active remediations to define max timeout values for specific types of requests. For example, you can set all third-party APIs that you know are further away to a higher timeout than those with local servers. This allows you to manage these limits separate from your codebase, which makes experimentation easier. It also makes adapting to unexpected network conditions easier.&lt;/p&gt;

&lt;p&gt;Whatever you do, don't neglect timeouts. Don't assume the defaults are safe, and don't assume the network is reliable. Keep your applications resilient against problems that third-party APIs may experience and your users will never know when major issues happen. If you want to learn more about Bearer and our active remediation features, &lt;a href="https://www.bearer.sh/" rel="noopener noreferrer"&gt;give our in-app agent's a try today&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>api</category>
      <category>http</category>
    </item>
    <item>
      <title>API Security Best Practices</title>
      <dc:creator>Mark Michon</dc:creator>
      <pubDate>Wed, 07 Oct 2020 09:38:59 +0000</pubDate>
      <link>https://dev.to/bearer/api-security-best-practices-3gjl</link>
      <guid>https://dev.to/bearer/api-security-best-practices-3gjl</guid>
      <description>&lt;p&gt;By nature, APIs are meant to be used. Even if all of your users are internal, security problems can still arise. To help with this, we've assembled a list of best practices to keep in mind when securing and locking-down an API or web service.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use HTTPS
&lt;/h2&gt;

&lt;p&gt;The web has moved past standard HTTP. With browser vendors flagging URLs that don't use a secure layer, it's time to do the same for your API. HTTPS uses Transport Layer Security (TLS) to encrypt traffic. This means communication between the client and server is encrypted. For your API, this means the content sent from your API is secured from third-parties, but more importantly it means that the access credentials are secured.&lt;/p&gt;

&lt;h2&gt;
  
  
  Authenticate
&lt;/h2&gt;

&lt;p&gt;Speaking of access credentials, the clearest way to avoid unexpected use of your API is to ensure proper authentication. Authentication is how you allow or prevent access to the API. Even publicly available APIs that are free to use should consider an authentication strategy. This allows you to limit or remove users that abuse the API, and also protect your users by giving them the ability to reset their credentials if needed. You can learn more about types of API authentication in our article on &lt;a href="https://blog.bearer.sh/the-three-most-common-api-authentication-methods/"&gt;the three most common authentication methods&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Authorize
&lt;/h2&gt;

&lt;p&gt;Authentication's sibling is authorization. Where authentication is concerned with who the user of your API is, authorization focuses on what they have access to. For example, free plan users may only be authorized to access a subset of your full API. When you think about integrations like social login, the user &lt;em&gt;authorizes&lt;/em&gt; your application to read their profile data from the social platform.&lt;/p&gt;

&lt;h2&gt;
  
  
  Secure endpoints AND resources (Object level authorization)
&lt;/h2&gt;

&lt;p&gt;It's common to secure an endpoint or set of endpoints through authorization. A more future-proof approach is to secure the individual resources as well. This prevents misconfigured, endpoint-level authorization from reaching your data. It also means that the endpoints themselves aren't restricted by user type, but instead the resource controls who can and cannot view it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rate limit
&lt;/h2&gt;

&lt;p&gt;When we think of security, we often think of inappropriate access. It can also be useful to think of security as managing resources. Rate-limiting is a technique for throttling the usage of an API. It can protect your resources financially, but also ensure that your servers aren't overloaded by a flood of requests at one time. Many rate-limiting approaches are time-based. They can be set for a billing period to handle overall usage, as well as use a "burst" approach to limit large influxes of requests. If you've ever seen the &lt;a href="https://blog.bearer.sh/error-429-too-many-requests-what-to-do-when-youve-been-rate-limited/"&gt;429 HTTP status code&lt;/a&gt;, you've experienced rate-limiting.&lt;/p&gt;

&lt;h2&gt;
  
  
  Validate and sanitize input
&lt;/h2&gt;

&lt;p&gt;One of the oldest attack points for web applications is input fields. The way we access data may have changed, but the need to validate any user input hasn't. Client-side validation is helpful for preventing mistakes and improving the user experience, but your API needs to also validate and sanitize all input before acting on it. Sanitization strips malicious or invalid code from requests. Validation ensures that the data meets the necessary criteria that your resources expect. This could be type and shape, or even factors like password structure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Expose only what is needed
&lt;/h2&gt;

&lt;p&gt;It can be tempting to take a shortcut and directly map data models to endpoints. Not only can this provide overly-verbose responses and increase bandwidth usage, but it can also expose data that users don't need access to. For example, consider a &lt;code&gt;/user&lt;/code&gt; endpoint that returns the user's profile. It may need some basic information about the user, but it doesn't need the user's password or access levels.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configure error messages
&lt;/h2&gt;

&lt;p&gt;In addition to sanitizing data that goes into your API, you'll want to sanitize the information that comes out of it. Error messages play a key role in helping users understand that a problem occurred, but make sure not to leak any sensitive data. Providing end-users with details about the structure of your internal code can open up areas for attackers to focus on. Make sure to configure error messages to provide enough information to help users debug and enough for them to report problems, but not enough to expose the inner workings of your application or sensitive data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Don't expose sensitive info
&lt;/h2&gt;

&lt;p&gt;To build on protecting sensitive data, make sure not to expose details in &lt;a href="https://jwt.io/"&gt;JSON web tokens&lt;/a&gt; (JWTs) or cookies. The body of a JWT have the illusion of being secure, but can easily be decoded. Because of this, you should avoid including user information that could be used to access your application. The same advice goes for URLs as well. Make sure query strings aren't exposing sensitive details.&lt;/p&gt;

&lt;h2&gt;
  
  
  Assess your dependencies
&lt;/h2&gt;

&lt;p&gt;We no longer develop in a silo. A good portion of every codebase now contains libraries, middleware, and a variety of dependencies from outside sources. While it is generally safe to assume that popular packages are "battle-tested", that doesn't mean they aren't completely safe from vulnerabilities. Make sure to assess your dependencies. Are they well maintained? Are you using the latest version? Is there a history of problems? Perhaps more importantly: Do you really need a library for what you're doing?&lt;/p&gt;

&lt;h2&gt;
  
  
  Allow users to track and reset authentication keys
&lt;/h2&gt;

&lt;p&gt;One additional way to improve the security of your own API is to allow users to reset their credentials and monitor their own usage. A common mistake is not allowing users to reset their API keys. If a consumer of your API exposes their key accidentally, or it is taken maliciously, the problem now directly affects your API. Instead, create a means for them to manage access.&lt;/p&gt;

&lt;h2&gt;
  
  
  Standardize auth across your services
&lt;/h2&gt;

&lt;p&gt;We've seen the big players in API like Google, Microsoft, and Amazon standardize the authorization and authentication process for their APIs. Consider a centralized means of doing this, like using an &lt;a href="https://blog.bearer.sh/what-is-an-api-gateway/"&gt;API gateway&lt;/a&gt; or a dedicated point of entry for handling authentication requests.&lt;/p&gt;

&lt;h2&gt;
  
  
  Follow standard guidelines from OWASP
&lt;/h2&gt;

&lt;p&gt;In addition to these best practices, consider adopting recommendations from &lt;a href="https://owasp.org/"&gt;The Open Web Application Security Project&lt;/a&gt; (OWASP). They offer platform-specific guides as well as an upcoming API-specific guide, The &lt;a href="https://owasp.org/www-project-api-security/"&gt;API Security Top 10&lt;/a&gt;. Beyond securing your API on a code-level, you'll also want to ensure that your servers and infrastructure are configured properly to avoid unauthorized access.&lt;/p&gt;

&lt;h2&gt;
  
  
  Protecting your API from other APIs
&lt;/h2&gt;

&lt;p&gt;If your API relies on third-party APIs, consider implementing a solution like &lt;a href="https://bearer.sh"&gt;Bearer&lt;/a&gt;. Integrating the Bearer Agent will allow you to track, observe, react, and receive alerts when an API isn't performing as expected. Try out &lt;a href="https://bearer.sh"&gt;Bearer&lt;/a&gt; today, and connect with us &lt;a href="https://twitter.com/BearerSH"&gt;@BearerSH&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>api</category>
      <category>security</category>
      <category>devops</category>
    </item>
    <item>
      <title>Top Tools to Make Debugging APIs Easier</title>
      <dc:creator>Mark Michon</dc:creator>
      <pubDate>Tue, 06 Oct 2020 15:09:20 +0000</pubDate>
      <link>https://dev.to/bearer/top-tools-to-make-debugging-apis-easier-3h3h</link>
      <guid>https://dev.to/bearer/top-tools-to-make-debugging-apis-easier-3h3h</guid>
      <description>&lt;p&gt;Integrating with APIs can be challenging. Each with its own &lt;a href="https://blog.bearer.sh/best-practices-for-navigating-api-documentation/" rel="noopener noreferrer"&gt;documentation format&lt;/a&gt;, SDK patterns, and authentication quirks. Once you get the integration up and running, the harder step is testing and debugging any problems. This part can be exploratory—before you finish building—or as part of problem resolution.&lt;/p&gt;

&lt;p&gt;While you can certainly debug within your codebase, by testing methods and reviewing logs, it can be beneficial to isolate the API calls by using one of the many API testing tools available.&lt;/p&gt;

&lt;p&gt;Rather than list the pros and cons of each, let's focus on what makes each tool unique and worth trying.&lt;/p&gt;

&lt;h2&gt;
  
  
  Postman
&lt;/h2&gt;

&lt;p&gt;Cost: Free + Paid Plans&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.bearer.sh%2Fcontent%2Fimages%2F2020%2F09%2Fpostman.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%2Fblog.bearer.sh%2Fcontent%2Fimages%2F2020%2F09%2Fpostman.png" alt="postman"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://postman.com" rel="noopener noreferrer"&gt;Postman&lt;/a&gt; is an institution in this space. It's been around for years, and went from a small app that made API calls into the full ecosystem that it is today. While Postman's primary use case is building and managing your own APIs, their emphasis on encouraging third-parties to publish collections has made it a great tool for exploring and debugging web services. These collections are what make Postman a fantastic tool for debugging external API calls.&lt;/p&gt;

&lt;p&gt;Some providers, like Zendesk, &lt;a href="https://developer.zendesk.com/rest_api/docs/sunshine/custom_objects_api" rel="noopener noreferrer"&gt;link directly to their Postman collections&lt;/a&gt; in their documentation. Others can be found on Postman's &lt;a href="https://explore.postman.com/" rel="noopener noreferrer"&gt;Explore&lt;/a&gt; page, and then opened within the Postman app. Once installed, you can explore endpoints and resources with minimal setup.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://postman.com" rel="noopener noreferrer"&gt;Learn more about Postman&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hoppscotch
&lt;/h2&gt;

&lt;p&gt;Cost: Free&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.bearer.sh%2Fcontent%2Fimages%2F2020%2F09%2Fhoppscotch.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%2Fblog.bearer.sh%2Fcontent%2Fimages%2F2020%2F09%2Fhoppscotch.png" alt="hoppscotch"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://hoppscotch.io/" rel="noopener noreferrer"&gt;Hoppscotch&lt;/a&gt; started as a faster, browser-first alternative to Postman, called Postwoman. It has since been rebranded and continues to add features. Its main benefits are speed and availability. It is also &lt;a href="https://github.com/hoppscotch/hoppscotch" rel="noopener noreferrer"&gt;open source&lt;/a&gt;, and can even run as a browser extension or progressive web app (PWA).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://hoppscotch.io" rel="noopener noreferrer"&gt;Learn more about Hoppscotch&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Paw
&lt;/h2&gt;

&lt;p&gt;Cost: Free Trial, then $49.99&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.bearer.sh%2Fcontent%2Fimages%2F2020%2F09%2Fpaw.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%2Fblog.bearer.sh%2Fcontent%2Fimages%2F2020%2F09%2Fpaw.png" alt="paw"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Moving on to platform-specific applications, &lt;a href="https://paw.cloud/" rel="noopener noreferrer"&gt;Paw&lt;/a&gt; is a paid Mac application for interacting with APIs. Like many of the others, it's core focus is on providing a tool to build, test, and document your own APIs. Perhaps Paw's greatest selling point is the UI. Compared to many of the other application's on this list, it really feels like quality Mac-first software. It also offers Team functionality, and an interesting feature called Pawprint that lets you share request/response pairs via a URL, even if the receiver doesn't use Paw.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://paw.cloud" rel="noopener noreferrer"&gt;Learn more about Paw&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Insomnia
&lt;/h2&gt;

&lt;p&gt;Cost: Free + Paid plans.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.bearer.sh%2Fcontent%2Fimages%2F2020%2F09%2Finsomnia.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%2Fblog.bearer.sh%2Fcontent%2Fimages%2F2020%2F09%2Finsomnia.png" alt="insomnia"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://insomnia.rest/" rel="noopener noreferrer"&gt;Insomnia&lt;/a&gt; is another API client that lets you design, debug, and test APIs. Unlike some of the other "all-inclusive" applications, Insomnia splits the API designer functionality into a seperate app. This makes the UI much more approachable, and makes it easier to quickly try out a new request without excess setup and configuration.&lt;/p&gt;

&lt;p&gt;One additional tool that you can find in their documentation is a CLI version called Inso. It allows you to use the functionality from both their core Insomnia client as well as the designer app, right from the command line, and even from within CI/CD environments.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://insomnia.rest/" rel="noopener noreferrer"&gt;Learn more about Insomnia&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fiddler
&lt;/h2&gt;

&lt;p&gt;Cost: Free plan + additional Paid plans&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.bearer.sh%2Fcontent%2Fimages%2F2020%2F09%2Ffiddler.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%2Fblog.bearer.sh%2Fcontent%2Fimages%2F2020%2F09%2Ffiddler.png" alt="fiddler"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;While the rest of the applications in this list are centered around allowing you to directly interface with APIs, &lt;a href="https://www.telerik.com/fiddler" rel="noopener noreferrer"&gt;Fiddler&lt;/a&gt; takes a different approach. It is more of a general purpose web debugging tool. It acts as a proxy to capture local requests between your device and the internet. This means you can run your application locally, and inspect any outgoing requests and incoming responses from the Fiddler application.&lt;/p&gt;

&lt;p&gt;This approach can be useful for live-debugging, but it also allows you to mock requests and responses that match specific rules. Combined with features around creating collections of requests and responses, and the ability to collaborate with a team, this approach could really help debugging more complex API problems.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.telerik.com/fiddler" rel="noopener noreferrer"&gt;Learn more about Fiddler&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Finding the right tool
&lt;/h2&gt;

&lt;p&gt;Choosing the right tool, not just for the task, but also for your workflow can be a challenge. Fortunately, all of the options we've looked at here are free or offer free trials to get you started. They can all help make exploring and debugging APIs easier. When it comes to debugging API problems in your live site, Bearer has a solution. We can detect problems automatically, help you track API performance, and you can enable detailed rules to watch for edge cases. &lt;a href="https://www.bearer.sh" rel="noopener noreferrer"&gt;Check out Bearer today&lt;/a&gt;, and take control of your API usage.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>webdev</category>
      <category>api</category>
      <category>todayisearched</category>
    </item>
    <item>
      <title>Sort, Filter, and Remap API Data in Python</title>
      <dc:creator>Mark Michon</dc:creator>
      <pubDate>Wed, 30 Sep 2020 13:30:17 +0000</pubDate>
      <link>https://dev.to/bearer/sort-filter-and-remap-api-data-in-python-5i</link>
      <guid>https://dev.to/bearer/sort-filter-and-remap-api-data-in-python-5i</guid>
      <description>&lt;p&gt;Are you taking data from an API in the format the web services gives it to you? You should not dictate the structure of data inside your application based on how an API provider structures their data. Instead, you can take advantage of the power of Python's list manipulation techniques to sort, filter, and reorganize data in ways that best suit your needs.&lt;/p&gt;

&lt;p&gt;In this article, we'll explore a few methods of using native Python features to sort, filter, and remap data from an external REST API that you can then use within your application, or pass down to a client as part of your own API. Looking for techniques to do this in Javascript? &lt;a href="https://blog.bearer.sh/javascript-api-array-data-manipulation/"&gt;We wrote about that in a previous article&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To follow along, you'll need to have Python3 installed and be familiar with running Python code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Retrieving data from an API
&lt;/h2&gt;

&lt;p&gt;To get started, we'll need some data to manipulate. For the examples in this article, we can use GitHub's v3 REST API and its &lt;code&gt;search/repositories&lt;/code&gt; endpoint. The endpoint takes a few parameters, but we'll use &lt;code&gt;q&lt;/code&gt; to pass in the &lt;code&gt;Bearer&lt;/code&gt; search query, and &lt;code&gt;per_page&lt;/code&gt; to limit the results to 10. This makes it easier to follow along if you are printing results to the console, but feel free to increase the returned results per page if you want a larger dataset to work with. You can also change the search query to anything you like, as it won't affect the manipulations that we'll perform.&lt;/p&gt;

&lt;p&gt;You can use any HTTP client, but our examples will be in Requests. Begin by installing &lt;code&gt;requests&lt;/code&gt; and importing it into your project.&lt;/p&gt;

&lt;p&gt;To install it, use &lt;code&gt;pip&lt;/code&gt; (or pip3, depending on your local setup):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;requests
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, import requests and set up the API call.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_repos&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
  &lt;span class="n"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;https://api.github.com/search/repositories?q=bearer&amp;amp;per_page=10&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;items&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;# Returns the value of the 'items' key from the JSON response body
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code above defines a function, &lt;code&gt;get_repos&lt;/code&gt; that will make the API call and return only the part of the response that we are interested in. In this case, the &lt;code&gt;items&lt;/code&gt; list on the JSON response. From this point forward, whenever we need the items data, we can assign it to a variable with &lt;code&gt;x = get_repos()&lt;/code&gt;. This will leave us with a &lt;code&gt;list&lt;/code&gt; of &lt;code&gt;dict&lt;/code&gt;, or dictionary, data types.&lt;/p&gt;

&lt;p&gt;Now with the setup out of the way, we can begin manipulating the data from the API.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sorting results in Python
&lt;/h2&gt;

&lt;p&gt;While many APIs allow you to sort the results in some way, rarely do you have access to sort by any property. GitHub, for example, allows sorting by stars, forks, help-wanted-issues, and how recently a repo has been updated. If you want a different sorting method, you'll need to handle this on your own. One thing to keep in mind is that we are only going to sort the results we retrieve. This means that if you capture the first ten results, sort them, then capture the next 10 results, they will not all be in the right order. If working with large datasets, it's best to capture all the data before sorting to avoid repeating the work on the same set of data multiple times.&lt;/p&gt;

&lt;p&gt;Python offers the &lt;a href="https://docs.python.org/3/library/functions.html#sorted"&gt;&lt;code&gt;sorted&lt;/code&gt; built-in function&lt;/a&gt; to make sorting lists easier. &lt;code&gt;sorted&lt;/code&gt; takes the list to you want to sort, and a &lt;code&gt;key&lt;/code&gt; representing the value to use when sorting the results. Let's take the following example: Sort the repositories by open issue count, from fewest issues to most issues.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# This line can be used in each example, but you only need it once in your file
&lt;/span&gt;&lt;span class="n"&gt;repos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_repos&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;fewest_issues_sort&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;sorted&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;repos&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;open_issues_count&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code above passes &lt;code&gt;repos&lt;/code&gt; in to the &lt;code&gt;sorted&lt;/code&gt; function, and then uses a lambda function for the &lt;code&gt;key&lt;/code&gt;. Lambda functions in Python are anonymous functions that you can use in-line without defining them elsewhere. They are great for use-cases like ours. This lambda is saying: "pass each iteration of repos to this function as &lt;code&gt;repo&lt;/code&gt;, then return its &lt;code&gt;open_issues_count&lt;/code&gt;." The sorted function uses the open issues count as the key. The result is a new list of dictionaries sorted by fewest issues to most issues.&lt;/p&gt;

&lt;p&gt;What if you want to reverse the order to show repos with the highest issue count first? You can achieve this with the &lt;code&gt;reverse&lt;/code&gt; argument in &lt;code&gt;sorted&lt;/code&gt;. By setting &lt;code&gt;reverse&lt;/code&gt; to &lt;code&gt;True&lt;/code&gt; the same logic will apply, but in reverse.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;most_issues_sort&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;sorted&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;repos&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;open_issues_count&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;reverse&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can use the same technique to sort by any value.&lt;/p&gt;

&lt;h2&gt;
  
  
  Filtering list data with Python
&lt;/h2&gt;

&lt;p&gt;Filters pair well with sorting. They allow you to reduce a list down to only the entries that matter for your needs. There are a variety of ways to filter a list, but they all use the same concept of building a new list from a subset of the original list's entries.&lt;/p&gt;

&lt;p&gt;One of the most effective ways to do this is using &lt;a href="https://docs.python.org/3/tutorial/datastructures.html#list-comprehensions"&gt;list comprehension&lt;/a&gt;. List comprehension is a method for creating lists, but it can also simplify complex loops into shorter expressions. Let's take an example where we only want repositories in our list that have a description filled out.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Fetch the repos if you haven't already
&lt;/span&gt;&lt;span class="n"&gt;repos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_repos&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;repos_with_descriptions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;repo&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;repo&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;repos&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;description&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code above does a lot with a single line, so let's break it down. It assigns &lt;code&gt;repos_with_descriptions&lt;/code&gt; to a new list, &lt;code&gt;[ ]&lt;/code&gt;. The first &lt;code&gt;repo&lt;/code&gt; in &lt;code&gt;repo for&lt;/code&gt; represents what we want to add to the new list. The next part &lt;code&gt;repo in repos&lt;/code&gt; should look familiar from any for-in loop. Finally, the end is our condition: &lt;code&gt;if repo['description'] is not None&lt;/code&gt;. When a description is not set in the GitHub API, it returns &lt;code&gt;null&lt;/code&gt; to the JSON response. Python interprets this as &lt;code&gt;None&lt;/code&gt;, so we check to see if the description is &lt;em&gt;not&lt;/em&gt; set to &lt;code&gt;None&lt;/code&gt; since we only want repositories with a description.&lt;/p&gt;

&lt;p&gt;What if we want two conditions? For example, only repositories that have a description and a homepage URL set.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;repos_with_desc_and_home&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;repo&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;repo&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;repos&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;description&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;homepage&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As with our previous example, this code says: "Make a new list made up of each &lt;code&gt;repo&lt;/code&gt; in &lt;code&gt;repos&lt;/code&gt;, but only include those where the description is not &lt;code&gt;None&lt;/code&gt; and the homepage is not &lt;code&gt;None&lt;/code&gt;."&lt;/p&gt;

&lt;p&gt;In both examples we've used the &lt;code&gt;is not&lt;/code&gt; operator. Let's look at a more conventional condition and only include repositories with 100 or more stars.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;popular_repos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;repo&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;repo&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;repos&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;stargazers_count&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code again uses list comprehension, but this time includes a more traditional greater-than-or-equal condition to compare values. You could also implement any of these examples with your preferred looping and list-generation methods.&lt;/p&gt;

&lt;h2&gt;
  
  
  Remapping or normalizing data
&lt;/h2&gt;

&lt;p&gt;Sometimes an API returns more information than you need. GraphQL solves this by allowing the client to specify exactly the data it needs, but for now most APIs are still REST-like. If you need to reduce the data down to only a few properties before you interact with it or send it on to other parts of your app, you can do so by iterating over the list and building a new one with only the parts you want.&lt;/p&gt;

&lt;p&gt;Loops or list comprehension can do this, but we will use Python's &lt;code&gt;map&lt;/code&gt; function. &lt;code&gt;map&lt;/code&gt; applies a function to every item in an iterable. Let's look at an example where we take the original &lt;code&gt;repos&lt;/code&gt; list and simplify it into fewer key/value pairs with map.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;simplify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;url&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;html_url&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;owner&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;owner&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;login&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;description&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;description&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;stars&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;stargazers_count&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;new_repos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;simplify&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;repos&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, &lt;code&gt;map&lt;/code&gt; receives the &lt;code&gt;simplify&lt;/code&gt; function which will run over each item in &lt;code&gt;repos&lt;/code&gt;. You can use this same method to manipulate the data further, normalize values, and even strip sensitive information.&lt;/p&gt;

&lt;h2&gt;
  
  
  Beyond the basics
&lt;/h2&gt;

&lt;p&gt;The techniques mentioned in this article are a great starting point to handle the majority of your use cases. API's mostly return JSON, which Python can convert into dictionaries. In our examples, we captured the &lt;code&gt;items&lt;/code&gt; list from the response dictionary and used it alongside many built-in Python functions to iterate over the data.&lt;/p&gt;

&lt;p&gt;Whether the data coming from an API is the core of your product offering, or only a part of the value you provide to your users, you need to be able to manipulate it to best suit your needs. You also need to know that the source of this data is reliable.&lt;/p&gt;

&lt;p&gt;How vital is this API data to the success of your app? What happens when the APIs experience performance problems or outages? There are safeguards you can put in place to avoid and manage downtimes and &lt;a href="https://blog.bearer.sh/api-integration-best-practices/"&gt;protect your integrations&lt;/a&gt; from failure. At Bearer we're building a solution that automatically monitors API performance, notifies you of problems, and can even intelligently react when a problem happens. &lt;a href="https://www.bearer.sh"&gt;Learn more about Bearer&lt;/a&gt; and give it a try today.&lt;/p&gt;

</description>
      <category>python</category>
      <category>beginners</category>
      <category>webdev</category>
      <category>api</category>
    </item>
    <item>
      <title>API Monitoring: What should you measure?</title>
      <dc:creator>Mark Michon</dc:creator>
      <pubDate>Wed, 23 Sep 2020 13:02:54 +0000</pubDate>
      <link>https://dev.to/bearer/api-monitoring-what-should-you-measure-2pjn</link>
      <guid>https://dev.to/bearer/api-monitoring-what-should-you-measure-2pjn</guid>
      <description>&lt;p&gt;When it comes to monitoring third-party APIs and web services, what you monitor is as important as how you monitor. Data is useful, but actionable data is where the true value is. Below we've listed the most common and valuable metrics to monitor when relying on third-party API integrations and web services. Accurate monitoring and alerting can provide your business with the data it needs to make decisions about which APIs to use, how to build resilient applications, and where to focus your engineering efforts.&lt;/p&gt;

&lt;p&gt;Here are the metrics that we recommend when you start to monitor an API or web services:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Latency&lt;/li&gt;
&lt;li&gt;Response Time&lt;/li&gt;
&lt;li&gt;Availability&lt;/li&gt;
&lt;li&gt;Consumption&lt;/li&gt;
&lt;li&gt;Failure rate&lt;/li&gt;
&lt;li&gt;Status Codes&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Latency
&lt;/h2&gt;

&lt;p&gt;Latency is the time the message spends “on the wire”. Here, the shorter the number, the better. Latency can be caused by the connection between your server and the API server. It can also be caused by delays that occur between your server and the API server. This may be the result of network traffic or resource overload—where throttling the requests might accommodate the heavy load.&lt;/p&gt;

&lt;p&gt;To monitor latency, the web service needs to track timestamps for the outgoing and incoming requests and compare them to past and future requests over a given time. This can still be tricky, as the responses from the server will also be affected by response time. If available, pinging an endpoint or calling a health-check endpoint can be the best way to receive an accurate latency estimate.&lt;/p&gt;

&lt;p&gt;This evaluation can be useful when positioning servers geographically. By determining the lowest latency your business can make decisions as to which provider to select. You can also select specific regional provider services if it is determined that the latency is the true cause for delayed responses, or select different providers if the response time of their resources is the problem. In actual practice, latency and response time will often be combined as a single value.&lt;/p&gt;

&lt;h2&gt;
  
  
  Response Time
&lt;/h2&gt;

&lt;p&gt;Where latency takes into account the delays in the network itself, response time is the time it takes a service to respond to a request. This can be harder to track with third-party APIs and web services, as the latency to send and receive data is part of the response time. You can estimate response time by comparing the response time across multiple resources on a given API. From this, you can estimate the shared latency between the API's servers and your servers, and decide what the true value is.&lt;/p&gt;

&lt;p&gt;The response time has a direct effect on your application's performance. Delays in the response of an API will result in slower interactions for your users. You can avoid this by ensuring your chosen API providers have response time guarantees, or by implementing a solution that uses a fallback API or cached resources when spikes are detected.&lt;/p&gt;

&lt;h2&gt;
  
  
  Availability
&lt;/h2&gt;

&lt;p&gt;The availability of an API can be described as either downtime or uptime. Both are based on the same data, but can tell a different story depending on the context.&lt;/p&gt;

&lt;p&gt;Availability is perhaps the easiest metric to keep track of. Downtime errors are recognizable and sometimes expected as an API provider will announce scheduled outages. However, even the most reliable APIs experience unforeseen downtimes. Downtime can be presented as individual events, or as an overall average across a given period. While downtime quotas and assurances such as "99.999% uptime" can be valuable when assessing an API provider, even the smallest downtime can have large impacts on your application.&lt;/p&gt;

&lt;p&gt;Many APIs rely on external providers such as Amazon Web Services (AWS), Microsoft Azure, and Google Cloud Services. As a result, the downtimes of an individual web service provider are also now dependent on a third-party that your application does not directly do business with. Even if the API provider's services are running as expected, the third-party may not be. As a result, when large downtimes occur, you will want to have a fallback in place that does not rely on the same underlying provider as the original API.&lt;/p&gt;

&lt;p&gt;While similar to downtime in the way it is measured, the uptime of an API can provide insight into business decisions. If you know that one API has better uptime during key business hours for your customers, you can use this metric to move between providers.&lt;/p&gt;

&lt;p&gt;Where some stakeholders may respond to downtime when selecting which API provider to drop, others may be more likely to respond to uptime when considering which to select. These values are linked, however, they can tell a different data story.&lt;/p&gt;

&lt;h2&gt;
  
  
  Consumption
&lt;/h2&gt;

&lt;p&gt;It can be easy to forget usage, or consumption, when monitoring APIs. Internal APIs may not require a usage metric, but telemetry into third-party API consumption can aid in making business decisions. Estimating costs when consuming a web service can be difficult without the appropriate data. Consumption can be evaluated as a whole, or in bursts. Some API providers bill on a monthly scale, but some may have rate limits on their pricing tiers that also watch for usage over a smaller time window.&lt;/p&gt;

&lt;p&gt;By keeping track of consumption and setting alerts for high usage, you can avoid unnecessary costs. Additionally, recognizing when APIs are not being used can also be beneficial. A lack of consumption is a sign that an API is still part of your codebase, but may not be vital to your application. In this case, you can adjust feature priority and gain insight into the usage of your application.&lt;/p&gt;

&lt;p&gt;Consumption is best viewed as a running value, and filterable by a time window. This allows dashboards to provide an overview, as well as granular details about when an API is being used&lt;/p&gt;

&lt;h2&gt;
  
  
  Failure rate
&lt;/h2&gt;

&lt;p&gt;There are a variety of reasons a request will fail. When a request to a third-party API or web service fails, it may be from user error, API downtime, rate limiting, or a variety of network-related issues. While API failures can sometimes be caused by your application, when it comes to tracking third-party APIs you want to focus primarily on failure rates out of your control.&lt;/p&gt;

&lt;p&gt;Tracking failures and determining failure rates can aid in:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Reporting problems to the API provider&lt;/li&gt;
&lt;li&gt;Deciding between multiple API providers&lt;/li&gt;
&lt;li&gt;Making informed decisions related to fallback scenarios&lt;/li&gt;
&lt;li&gt;Building resiliency around certain resources&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Some errors may come from invalid requests. These can tell you that your application needs to adjust internal validation before making a request. Errors that come from server-related issues, like status codes in the 400 and 500 ranges, are a sign that the problem is likely with the API or web service provider.&lt;/p&gt;

&lt;h2&gt;
  
  
  Status Codes
&lt;/h2&gt;

&lt;p&gt;Tracking HTTP responses can give you granular details about an individual API, but tracking specific status codes can give you better insight into the type of problems. For example, some API providers will respond with a &lt;code&gt;200 OK&lt;/code&gt; status, even when an error occurred. This false metric may lead you to believe that everything is working as expected, but users may experience problems and your internal logging may tell a different story.&lt;/p&gt;

&lt;p&gt;Comparing status code metrics from API providers with internal error logs can provide additional insight into the true error rates of the third-party web services your application relies on.&lt;/p&gt;

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

&lt;p&gt;With these metrics in mind, your applications can better handle the unavoidable issues that will arise when relying on third-party integrations.&lt;/p&gt;

&lt;p&gt;Measuring all these metrics may sound like a daunting task. Fortunately, some developer tools, like &lt;a href="https://bearer.sh"&gt;Bearer&lt;/a&gt;, can aid in both monitoring many of these metrics and reacting to problems that arise &lt;em&gt;automatically&lt;/em&gt;.&lt;/p&gt;

</description>
      <category>api</category>
      <category>devops</category>
      <category>monitoring</category>
    </item>
    <item>
      <title>Use Javascript's Array Methods to Handle API Data</title>
      <dc:creator>Mark Michon</dc:creator>
      <pubDate>Mon, 21 Sep 2020 13:03:27 +0000</pubDate>
      <link>https://dev.to/bearer/use-javascript-s-array-methods-to-handle-api-data-4n8</link>
      <guid>https://dev.to/bearer/use-javascript-s-array-methods-to-handle-api-data-4n8</guid>
      <description>&lt;p&gt;&lt;em&gt;📣 This post originally appeared as &lt;a href="https://blog.bearer.sh/javascript-api-array-data-manipulation/"&gt;Use Javascript's Array Methods to Handle API Data&lt;/a&gt; on &lt;a href="https://blog.bearer.sh"&gt;The Bearer Blog&lt;/a&gt;.&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;Manipulating data is a core skill for any developer. In an API-driven environment, so much of the data you receive is formatted in a way that doesn't directly match the way that your application or UI needs it. Each web service and third-party API is different. This is where the ability to sort, normalize, filter, and manipulate the shape of data comes in.&lt;/p&gt;

&lt;p&gt;In this article, we'll explore some common ways to work with data in Javascript. To follow along, you'll need to be working with code in either Node.js or the Browser.&lt;/p&gt;

&lt;h2&gt;
  
  
  Retrieving data from an API
&lt;/h2&gt;

&lt;p&gt;Before we start, you need some data. For the rest of the examples in the article, we'll be using the data returned from a search of GitHub's v3 REST API. We'll use the &lt;code&gt;search/repositories&lt;/code&gt; endpoint to make a query for repositories matching a search term (the q parameter, in this case set to &lt;code&gt;bearer&lt;/code&gt;). We're also going to limit the number of results to 10 per page, and only one page. This makes it more manageable for our examples.&lt;/p&gt;

&lt;p&gt;Start by using Fetch to connect to the API, and wrap it in a function with some basic error handling. You can reuse the function later in each of our examples.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;apiCall&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://api.github.com/search/repositories?q=bearer&amp;amp;per_page=10&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you're using Node.js, you can use the &lt;code&gt;node-fetch&lt;/code&gt; package to add Fetch support. Install it to your project with &lt;code&gt;npm install -S node-fetch&lt;/code&gt;. Then, require it at the top of your project file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fetch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;node-fetch&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We'll also make use of async/await. If your platform (like some versions of Node.js) doesn't support top-level async/await, you'll need to wrap the code in an async function. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;example&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="c1"&gt;// Code here&lt;/span&gt;

    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;apiCall&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;// More code&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With the setup out of the way, let's get started handling the response data. The results from the API call provide you with an object that contains some general metadata, as well as an array of repositories with the key of &lt;code&gt;items&lt;/code&gt;. This lets you use a variety of techniques to iterate over the array and act upon the results. Let's look at some example use cases.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sorting results
&lt;/h2&gt;

&lt;p&gt;Many APIs, including GitHub's, allow you to sort the results by specific criteria. Rarely do you have full control over this. For example, GitHub's repository search only allows ordering by stars, forks, help-wanted-issues, and how recently an item was updated. If you need results in a different order, you'll have to build your own sorting function. Let's say you want to sort results by the number of open issues the repository has. This means the repository with the fewest issues should show first, and the repository with the most should show last.&lt;/p&gt;

&lt;p&gt;You can achieve this by using &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort"&gt;Array.sort&lt;/a&gt; along with a custom sort function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Sort by open issues&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sortByOpenIssues&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;repos&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;repos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;open_issues_count&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;open_issues_count&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// Run the apiCall function and assign the result to results&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;apiCall&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;// Call sort on the items key in results&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;sortByOpenIssues&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To understand what's happening, lets look at how sort works. The method expects a specific return value:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  A value less than 0 means the first value is greater than the second, and should come before it in the order.&lt;/li&gt;
&lt;li&gt;  A value of 0 means both values are equal.&lt;/li&gt;
&lt;li&gt;  A value greater than 0 means the second value is greater than the first, and should come before it in the order.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The easiest way to work with these conditions is to subtract the second value from the first. So in our code above, you subtract &lt;code&gt;b.open_issues_count&lt;/code&gt; from &lt;code&gt;a.open_issues_count&lt;/code&gt;. If the number of issues for "a" is greater, the result will be greater than 0. If they are equal, it will be zero. Finally, if b is greater the result will be a negative number.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;sort&lt;/code&gt; method handles all of the movement of items around for you, and returns a brand new array. In the example above, two values are compared, but you can use any calculation that results in the criteria mentioned above to sort the results of an array.&lt;/p&gt;

&lt;h2&gt;
  
  
  Filtering results
&lt;/h2&gt;

&lt;p&gt;Sorting changed the order of our data, but filtering narrows the data down based on specific criteria. Think of it as removing all of a certain color of candy from a bowl. You can use Javascript's built-in &lt;code&gt;filter&lt;/code&gt; method on arrays to handle this. Similar to &lt;code&gt;sort&lt;/code&gt;, the filter method will iterate over each item and return a new array. Any Let's look at a few filter scenarios.&lt;/p&gt;

&lt;p&gt;In the first, we'll create a filter that only shows repositories that contain a description.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Filter only repos that have descriptions&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;descriptionsOnly&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;repos&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;repos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;apiCall&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;descriptionsOnly&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this case ,we're returning the truthiness of &lt;code&gt;repo.description&lt;/code&gt; to represent whether the API returned a value or &lt;code&gt;null&lt;/code&gt;. If the current iteration in the loop returns &lt;code&gt;true&lt;/code&gt;, that iteration's item is pushed to the new array.&lt;/p&gt;

&lt;p&gt;What if we want only repositories that have both a description and homepage URL? You can modify the previous example to achieve this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Filter only repos with URL and description&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;homeAndDescription&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;repos&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;repos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;repo&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;homepage&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;apiCall&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;homeAndDescription&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using Javascript's AND operator (&amp;amp;&amp;amp;), you can check that both the description and URL exist. If they do, the whole expression returns true and the item in the array is added to the new array. If either are false, the whole expression is false and the iteration will not be added to the new array.&lt;/p&gt;

&lt;p&gt;What about something a little more complex? Lets say you want all repositories that have been updated after a certain date. You can do this by setting a threshold and comparing it to the &lt;code&gt;updated_at&lt;/code&gt; value on each repository.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Set a threshold&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;date_threshold&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;2020-08-01&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// Filter over results and compare the updated date with the cutoff date&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;filterByDate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;repos&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;cutoff_date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;repos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;repo&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;updated_at&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;date_threshold&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;apiCall&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;filterByDate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;date_threshold&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Just as in the previous example, the truthiness of the returned value in the function passed to filter determines if the item is added to the new array.&lt;/p&gt;

&lt;h2&gt;
  
  
  Changing the shape of data and format of data
&lt;/h2&gt;

&lt;p&gt;Sometimes the data you receive isn't what you need for your use case. It can either include too much, or it can be in the wrong format. One way to get around this is by normalizing the data. Data normalization is the process of structuring data to fit a set of criteria. For example, imagine these API interactions are happening on the server, but the client needs a subset of the data. You can re-shape the data before passing it down to the client.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;normalizeData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;repos&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;repos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;repo&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;html_url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;login&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;stars&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stargazers_count&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;apiCall&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;normalizeData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above code, the &lt;code&gt;map&lt;/code&gt; array method is used to iterate over the results. It returns a new array made up of the values you return. In this instance, the data from the repos is simplified to include only a few key/value pairs, and the names of the keys have been made more digestible.&lt;/p&gt;

&lt;p&gt;You can even use this time to modify any data. For example, you could wrap &lt;code&gt;repo.stargazers_count&lt;/code&gt; in &lt;code&gt;Number()&lt;/code&gt; to ensure the count was always a number and never a string.&lt;/p&gt;

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

&lt;p&gt;Managing the data you receive from an API is a critical part of any API integration. Every API will return a different shape of data, in their own format. The exception being GraphQL APIs that give you more control over the shape, and sometimes the sort order and filtering options.&lt;/p&gt;

&lt;p&gt;Whether you are using the data as part of a larger data-processing effort, or using it to improve the usefulness of your application to your users, you will need to perform some actions to make the data digestible for your app.&lt;/p&gt;

&lt;p&gt;These API integrations are integral to your application, but what happens when they fail? We've written here before about &lt;a href="https://blog.bearer.sh/circuit-breaker-design-pattern/"&gt;some of the actions&lt;/a&gt; you can take to &lt;a href="https://blog.bearer.sh/api-integration-best-practices/"&gt;protect your integrations&lt;/a&gt; from failure. At Bearer, we're also building a complete solution to monitor the performance, notify you of problems, and automatically remediate problems with the APIs your app relies on. &lt;a href="https://www.bearer.sh"&gt;Learn more about Bearer&lt;/a&gt;, and give it a try today.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>api</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Machine Learning APIs for Web Developers</title>
      <dc:creator>Mark Michon</dc:creator>
      <pubDate>Wed, 16 Sep 2020 14:55:13 +0000</pubDate>
      <link>https://dev.to/bearer/machine-learning-apis-for-web-developers-15k0</link>
      <guid>https://dev.to/bearer/machine-learning-apis-for-web-developers-15k0</guid>
      <description>&lt;p&gt;Machine learning (ML) used to be a tool limited to specialized developers and dedicated teams. Now, thanks to many web service providers and approachable tooling, your applications can use pre-build learning models and machine learning techniques the same way you would use any web service API. &lt;/p&gt;

&lt;p&gt;This is a quick way to test out and benefit from machine learning without having to invest in artificial intelligence, building your own learning models, or shaping your application around ML. In this article, we'll focus on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
The big players in ML APIs.&lt;/li&gt;
&lt;li&gt;
Smaller companies and startups offering API services.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What can you do with a machine learning API?
&lt;/h2&gt;

&lt;p&gt;When we talk about artificial intelligence (AI) and machine learning (ML) in these contexts, they will sometimes be used interchangeably. &lt;/p&gt;

&lt;p&gt;At a basic level, machine learning is the process of training a computer to understand the data it receives on a level deep enough to make decisions. Artificial intelligence is the decisions it makes and as a result, the decisions that your application uses.&lt;/p&gt;

&lt;p&gt;All the big web services players are now involved. Microsoft Azure, Google Cloud, Amazon Web Services, and the IBM Cloud all provide similar products with a few unique exceptions. The types of services offered revolve around the types of learning and prediction that your app needs. They can help you do things like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Focus on a specific part of an image the user uploads. Twitter, for example, crops image previews to center on text.&lt;/li&gt;
&lt;li&gt;Provide recommendations based on purchase or browsing history.&lt;/li&gt;
&lt;li&gt;Predict outcomes based on a set of inputs (forecasting).&lt;/li&gt;
&lt;li&gt;Handle language processing to translate text and autocomplete sentences.&lt;/li&gt;
&lt;li&gt;Provide conversation-style chat bots that can use sentiment analysis to better understand the customer.&lt;/li&gt;
&lt;li&gt;Detect anomalies in your data by looking at past trends.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Many providers allow you a way to build upon existing machine learning models of specific types. This allows developers to feed the machine information, without the need to deeply understand how everything works. &lt;/p&gt;

&lt;p&gt;For example, most APIs that provide computer vision or image recognition use a pre-built model that already knows what to look for in an image. They can detect common items like buildings, household objects, and animals. &lt;/p&gt;

&lt;p&gt;Your team's developers then provide images to the machine learning prediction API in the programming language you prefer, and it uses the pre-built model to make a prediction. Similar techniques can be used for tracking movement, facial recognition, and text analysis.&lt;/p&gt;

&lt;h2&gt;
  
  
  The big players in ML APIs
&lt;/h2&gt;

&lt;p&gt;When we talk about machine learning APIs, we are really talking about machine learning as a service (&lt;strong&gt;MLaaS&lt;/strong&gt;). Rather than run the full stack of ML tooling yourself you rely on a provider to handle the processing and, to some extent, the training of the machine.  &lt;/p&gt;

&lt;p&gt;Many providers now offer similar services at competitive price points. For the most part, you can stick with your preferred provider, but there are a few instances where some offer a better solution.&lt;/p&gt;

&lt;p&gt;Nearly every provider offers services like computer vision, facial recognition, text translation, and text-to-speech. Let's look at a brief overview of each provider, with a few of their services highlighted.&lt;/p&gt;

&lt;h3&gt;
  
  
  Amazon
&lt;/h3&gt;

&lt;p&gt;Amazon has expanded Amazon Web Services (AWS) to include a variety of ML and ML-adjacent services. The &lt;a href="https://aws.amazon.com/machine-learning/"&gt;Amazon machine learning APIs&lt;/a&gt; offer nice hooks into the AWS ecosystem.&lt;/p&gt;

&lt;p&gt;Key offerings:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Recommendations&lt;/strong&gt;: Their &lt;a href="https://aws.amazon.com/personalize/"&gt;Amazon Personalize&lt;/a&gt; service gives you the power to use a recommendation system similar to Amazon's to offer "related content" style recommendations to your users. It uses your own dataset, and a simplified interface to creating and training models.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Transcription&lt;/strong&gt;: One of the first to offer transcription services, &lt;a href="https://aws.amazon.com/transcribe/"&gt;Amazon Transcribe&lt;/a&gt; will let you transcribe recorded videos or even streams in near real-time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Code review&lt;/strong&gt;: &lt;a href="https://aws.amazon.com/codeguru/"&gt;Amazon CodeGuru&lt;/a&gt; is a newer offering that analyses your codebase and uses machine learning to alert you of expensive code and potentially problematic code. They use their own internal codebase and over 10,000 open source GitHub projects to train the machine learning models used by this API.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Amazon's pricing differs with each machine learning API and can be found on each APIs product page. You can see the full list of AWS' ML and AI-related offerings on the &lt;a href="https://aws.amazon.com/machine-learning"&gt;Machine Learning on AWS&lt;/a&gt; page. &lt;/p&gt;

&lt;p&gt;In addition to their machine learning APIs, Amazon also offers solutions for teams looking to host and deploy their own learning processing and ML applications.&lt;/p&gt;

&lt;h3&gt;
  
  
  Google
&lt;/h3&gt;

&lt;p&gt;Google's machine learning offerings are heavily focused on being a platform for hosting, training, and managing ML models. That said, they have begun to offer many more machine learning APIs for developers to take advantage of. &lt;/p&gt;

&lt;p&gt;Some of the more interesting APIs are centered around Google's &lt;a href="https://cloud.google.com/products/ai/building-blocks"&gt;AI Building Blocks&lt;/a&gt;. These are similar to drop-in tools that can add AI and ML features to existing apps without the need for in-house expertise.&lt;/p&gt;

&lt;p&gt;Key offerings:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Language Processing&lt;/strong&gt;: &lt;a href="https://app.surferseo.com/drafts/Cloud%20Translation"&gt;Translation&lt;/a&gt; is the most obvious machine learning API offered, but they also offer &lt;a href="https://cloud.google.com/text-to-speech"&gt;text-to-speech&lt;/a&gt;, &lt;a href="https://app.surferseo.com/drafts/Speech-to-Text"&gt;speech-to-text&lt;/a&gt;, &lt;a href="https://app.surferseo.com/drafts/Cloud%20Natural%20Language"&gt;sentiment analysis&lt;/a&gt;, and &lt;a href="https://cloud.google.com/dialogflow"&gt;dialog flow&lt;/a&gt; for conversational interfaces.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Vision&lt;/strong&gt;: Machine learning developers can build upon existing models that Google offers, but also take advantage of &lt;a href="https://cloud.google.com/vision"&gt;pre-built features like emotion detection, classification, text OCR&lt;/a&gt;, and more.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Google offers a generous free tier for the majority of its machine learning and AI products. Developers that need more from the Google cloud can view their &lt;a href="https://cloud.google.com/pricing/list"&gt;pricing information&lt;/a&gt; on an API by API basis.&lt;/p&gt;

&lt;h3&gt;
  
  
  Microsoft
&lt;/h3&gt;

&lt;p&gt;Microsoft's cloud services offering, Microsoft Azure, groups its machine learning APIs under the title of &lt;a href="https://docs.microsoft.com/en-gb/azure/cognitive-services/"&gt;Cognitive Services&lt;/a&gt;. With similar offerings to the other providers, services can be broken down into the key categories:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Vision&lt;/strong&gt;: Focused around APIs related to object detection, classification, and recognition. These services can do things like detect faces, recognize documents, and train custom models to identify images.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Language&lt;/strong&gt;: Just like most providers, Azure also offers translation, sentiment analysis, and natural language processing. Beyond this, they offer a few interesting APIs such as &lt;a href="https://docs.microsoft.com/en-gb/azure/cognitive-services/immersive-reader/"&gt;Immersive Reader&lt;/a&gt;, which adds additional information to text for learners.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Speech&lt;/strong&gt;: Developers can access the &lt;a href="https://docs.microsoft.com/en-gb/azure/cognitive-services/speech-service/"&gt;Speech Service&lt;/a&gt; API to generate synthetic speech. A new offering that stands out amongst the other providers is &lt;a href="https://docs.microsoft.com/en-gb/azure/cognitive-services/speaker-recognition/home"&gt;Speaker Recognition&lt;/a&gt;. It allows developers to identify and verify speakers using existing data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Decision&lt;/strong&gt;: The decision APIs offer tools like recommendations, similar to Amazon's offering, but also provide Content Moderation and a new &lt;a href="https://docs.microsoft.com/en-gb/azure/cognitive-services/anomaly-detector/"&gt;Anomaly Detection&lt;/a&gt; service. Anomaly detection analyses data to look for outliers over time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Search&lt;/strong&gt;: Utilizing the foundation of Microsoft's Bing search engine, this API falls under the cognitive services umbrella, even though many developers may not classify it as a machine learning API.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Like all of our providers in this list, Azure's pricing is on a usage basis. All services are managed from within the Azure Portal. See the breakdown for each API on their &lt;a href="https://azure.microsoft.com/en-us/pricing/details/cognitive-services/"&gt;pricing page&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  IBM
&lt;/h3&gt;

&lt;p&gt;Often forgotten next to AWS, Google Cloud, and Azure, IBM's web service offerings are vast. All of their AI/ML APIs are grouped under the &lt;a href="https://www.ibm.com/cloud/products#936026"&gt;Watson&lt;/a&gt; brand. While many of their offerings are similar to the other providers, here are a few interesting differentiators:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;DevOps insights&lt;/strong&gt;: Like Azure's anomaly detection, IBM offers &lt;a href="https://www.ibm.com/products/watson-aiops"&gt;Watson AIOps&lt;/a&gt; to help developers resolve and detect incidents.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automated Assistant&lt;/strong&gt;: Watson's big sell is its &lt;a href="https://www.ibm.com/cloud/watson-assistant/"&gt;Watson Assistant&lt;/a&gt;. It is an AI-powered chat interface for responding to customers. It works both as a text-chat on sites, but also on call systems to let users ask questions in natural language.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;While the audience for IBM services tends to skew toward the enterprise, they offer generous free tiers for teams and developers looking to try out their services. See pricing for individual APIs on their &lt;a href="https://www.ibm.com/cloud/pricing"&gt;pricing page&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  ML and AI Startups offering APIs
&lt;/h2&gt;

&lt;p&gt;The landscape of startups providing ML and AI APIs is a bit more volatile, with some going out of business after a few years. The big players dominate the space, but there are smaller startups and open source APIs that offer interesting takes on common features. These range from traditional web service APIs, to full software suites. Both traditional developers and learning developers alike will find value in services like language processing, image recognition, and more. Here are a few players in the space:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.kairos.com/"&gt;Kairos&lt;/a&gt;: Kairos offers a variety of services centered around facial recognition. Some of their features include &lt;strong&gt;face detection, verification, identification&lt;/strong&gt;, tracking, and insights into facial features like age and gender.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.textrazor.com/"&gt;TextRazor&lt;/a&gt;: A Natural Language Processing (NLP) API, TextRazor does more than attempt to understand the text. It works to &lt;strong&gt;provide additional meaning&lt;/strong&gt; by pulling useful information from the text, like business names and places, to provide more information about the intent and meaning behind the text.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://rxnlp.com/"&gt;RxNLP&lt;/a&gt;: Another API that aims to provide value to text content, RxNLP has a few APIs that do things like &lt;strong&gt;comparing the similarity of text&lt;/strong&gt; and group similar types of text.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://imagga.com/"&gt;Imagga&lt;/a&gt;: Imagga offers an array of image recognition services ranging from categorizing, automated cropping of key items, color extraction and modification, and even &lt;strong&gt;content moderation&lt;/strong&gt; of inappropriate images.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;More companies continue to spawn as the accessibility of ML and AI tooling increases. Expect to see startups targeted at specific industries to offer unique ML APIs in the future.&lt;/p&gt;

&lt;h2&gt;
  
  
  How should you choose a machine learning API?
&lt;/h2&gt;

&lt;p&gt;As we look over the available APIs from the providers above, we can see that they all offer similar services. Unless you need one of the more edge-case offerings, it is often best to stick with the platform that you already use. This allows billing, management, and credentials to all exist in one place.&lt;/p&gt;

&lt;p&gt;It is also important to consider maturity and performance. While large platform providers are more stable, they are still susceptible to downtime. &lt;/p&gt;

&lt;p&gt;Always make sure to use a monitoring and remediation tool when utilizing third-party APIs. &lt;/p&gt;

&lt;p&gt;At Bearer, we offer a tool to automatically detect anomalies, notify your team when problems happen, and even remediate API issues for your application. &lt;a href="https://bearer.sh/"&gt;Check it out and get started for free&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>cloud</category>
      <category>programming</category>
      <category>aws</category>
      <category>azure</category>
    </item>
    <item>
      <title>Making API Requests with Python</title>
      <dc:creator>Mark Michon</dc:creator>
      <pubDate>Wed, 29 Jul 2020 14:00:18 +0000</pubDate>
      <link>https://dev.to/bearer/making-api-requests-with-python-2h3i</link>
      <guid>https://dev.to/bearer/making-api-requests-with-python-2h3i</guid>
      <description>&lt;p&gt;Python is in the midst of a resurgence. It never went away, but usage now grows like never before. With machine learning developers and data scientists relying on Python, much of the web development ecosystem around the language continues to grow.&lt;/p&gt;

&lt;p&gt;One aspect that affects all three of these specializations is the powerful benefits of APIs. Pulling in data, and connecting to external services, is an essential part of any language. In this article, we'll look at the primary libraries for making HTTP requests, along with some common use cases that allow you to connect to an API in Python. Before that, we should ask an important question.&lt;/p&gt;

&lt;h2&gt;
  
  
  Is Python good for APIs?
&lt;/h2&gt;

&lt;p&gt;It seems like a strange question, but given the large web presence of Node.js and Ruby, you may think that Python isn't good for making API calls. This isn't true. In fact, Python has had a long and dedicated presence on the web, specifically with it's Flask and Django libraries.&lt;/p&gt;

&lt;p&gt;As Python is a powerful, accessible way to manipulate data, it makes sense to also use it for acquiring the data sources. This is where API calls come in. Let's start with the most popular Python HTTP library used for making API calls. &lt;strong&gt;Requests&lt;/strong&gt;.&lt;/p&gt;

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

&lt;p&gt;Requests is the accessible, leading library that developers use for making API requests in Python. It offers an interface to make HTTP requests &lt;em&gt;synchronously&lt;/em&gt;. Let's get right into some common types of requests you can make with Requests. The following examples will all assume that your project includes Requests. You can follow their &lt;a href="https://requests.readthedocs.io/en/master/user/install/#install"&gt;installation instructions&lt;/a&gt;, but the gist is:&lt;/p&gt;

&lt;p&gt;Install it via &lt;code&gt;pip&lt;/code&gt; or &lt;code&gt;pipenv&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;requests
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, make sure to import requests into your project&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Common types of API calls with Requests
&lt;/h3&gt;

&lt;p&gt;The most simple &lt;code&gt;GET&lt;/code&gt; request is intuitive.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;https://example.com&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As we can see with the &lt;code&gt;get&lt;/code&gt; method above, Requests offers shortcut methods for the HTTP verbs, including &lt;code&gt;POST&lt;/code&gt;, &lt;code&gt;PUT&lt;/code&gt;, &lt;code&gt;DELETE&lt;/code&gt;, &lt;code&gt;HEAD&lt;/code&gt;, and &lt;code&gt;OPTIONS&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The previous request is pretty simple. Let's look at more complex requests. Often, an APIs documentation will require that you pass query parameters to a specific endpoint. To pass query parameters, we can pass them into &lt;code&gt;get&lt;/code&gt; as the second argument.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;https://example.com&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Bearer&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;response&lt;/code&gt; variable contains the data returned by the API in our examples. There are three primary ways to access the data.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  As text, with &lt;code&gt;response.text&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  As bites with &lt;code&gt;response.content&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  As JSON with &lt;code&gt;response.json()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  Or as the raw response with &lt;code&gt;response.raw&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In addition to the body of the response, we can also access the status code with &lt;code&gt;response.status_code&lt;/code&gt;, the headers with &lt;code&gt;response.headers&lt;/code&gt;, and so on. You can find a full list of properties and methods available on &lt;code&gt;Response&lt;/code&gt; &lt;a href="https://requests.readthedocs.io/en/master/api/#requests.Response"&gt;in the requests.Response documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;As we saw with the &lt;code&gt;params&lt;/code&gt; argument, we can also pass headers to the request.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;https://example.com, headers={&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="n"&gt;example&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;header&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;: &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="n"&gt;Bearer&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;})
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we pass the &lt;code&gt;headers&lt;/code&gt; argument with a python dictionary of headers.&lt;/p&gt;

&lt;p&gt;The last common API call type we'll make is a full-featured &lt;code&gt;POST&lt;/code&gt;, with authentication. This will combine the previous headers technique with the use of the &lt;code&gt;data&lt;/code&gt; argument.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;https://example.com&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
&lt;span class="n"&gt;headers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Authorization&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Bearer example-auth-code&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Mark&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;mark@bearer.sh&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This sends the payload as form-encoded data. For most modern APIs, we often need to send data as JSON. In this next example, we use the built in json helper from &lt;strong&gt;requests&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;https://example.com&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
&lt;span class="n"&gt;headers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Authorization&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Bearer example-auth-code&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Mark&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;mark@bearer.sh&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will encode the payload as JSON, as well as automatically change the &lt;code&gt;Content-Type&lt;/code&gt; header to &lt;code&gt;application/json&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Requests is excellent for synchronous API calls, but sometimes your app may depend on asynchronous requests. For this, we can use an asynchronous HTTP library like &lt;a href="https://docs.aiohttp.org/en/latest/index.html"&gt;aiohttp&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  aiohttp
&lt;/h2&gt;

&lt;p&gt;When making asynchronous HTTP requests, you'll need to take advantage of some newer features in Python 3. While the requests library does have variations and plugins to handle asynchronous programming, one of the more popular libraries for async is aiohttp. Used together with the &lt;a href="https://docs.python.org/dev/library/asyncio.html"&gt;asyncio&lt;/a&gt;, we can use &lt;a href="https://docs.aiohttp.org/en/latest/index.html"&gt;aiohttp&lt;/a&gt; to make requests in an async way. The code is a little more complex, but provides all the additional freedom that async calls provide.&lt;/p&gt;

&lt;p&gt;To get started, we'll need to install &lt;code&gt;aiohttp&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Install &lt;code&gt;aiohttp&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;aiohttp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Common types of API calls with aiohttp
&lt;/h3&gt;

&lt;p&gt;We will begin with the same &lt;code&gt;GET&lt;/code&gt; request we saw earlier. To start, import both libraries, and define an async function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;asyncio&lt;/span&gt; &lt;span class="c1"&gt;#  [1]
&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;aiohttp&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="c1"&gt;# [2]
&lt;/span&gt;    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;aiohttp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ClientSession&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="c1"&gt;# [3]
&lt;/span&gt;    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;http://example.com&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="c1"&gt;# [4]
&lt;/span&gt;        &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;# [5]
&lt;/span&gt;        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;asyncio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="c1"&gt;# [6]
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the code above, we perform the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; We import the required libraries.&lt;/li&gt;
&lt;li&gt; Define &lt;code&gt;main&lt;/code&gt; as an async function.&lt;/li&gt;
&lt;li&gt; We set up a &lt;code&gt;ClientSession&lt;/code&gt; from &lt;code&gt;aiohttp&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt; We use the session to perform an HTTP GET request.&lt;/li&gt;
&lt;li&gt; Next, we await the response and print it.&lt;/li&gt;
&lt;li&gt; Finally, we use the &lt;code&gt;run&lt;/code&gt; method of Python's asyncio to call the asynchronous function.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you haven't worked with async in Python before, this may look strange and complicated compared to the earlier examples. &lt;em&gt;The makers of &lt;code&gt;aiohttp&lt;/code&gt; recommend setting a single session per application and opening/closing connections on the single session. To make our examples self-contained, I have left the examples in the less efficient format.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Next, let's look at a full-featured &lt;code&gt;POST&lt;/code&gt; with auth headers, like in the requests example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;
&lt;span class="c1"&gt;# ...
&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;aiohttp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ClientSession&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;http://example.com&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Authorization&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Bearer 123456&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Content-Type&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;application/json&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;title&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Try Bearer&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="c1"&gt;# [1]
&lt;/span&gt;
            &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;# [2]
&lt;/span&gt;            &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;asyncio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are a few differences between this example and the previous:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; The session uses the &lt;code&gt;post&lt;/code&gt; method, and passes in headers and json dictionaries in addition to the URL.&lt;/li&gt;
&lt;li&gt; We use the library's built-in &lt;code&gt;json&lt;/code&gt; method from the response to parse the returned json.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;With these two snippets, we're able to perform the majority of common API-related tasks. For additional features like file uploading and form data, take a look at &lt;a href="https://docs.aiohttp.org/en/latest/index.html"&gt;aiohttp's developer documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Additional libraries to try
&lt;/h2&gt;

&lt;p&gt;While &lt;em&gt;Requests&lt;/em&gt; is the most popular, you may find value in some of these additional libraries for more unique use cases.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://pypi.org/project/httpx/"&gt;httpx&lt;/a&gt;: &lt;code&gt;httpx&lt;/code&gt; offers both sync and async support. It also uses a requests-compatible API that will make moving between the two much easier. Currently the library is in a beta state with a 1.0 expected min-summer 2020, but it is worth keeping an eye on as it matures.&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://pypi.org/project/httpcore/"&gt;httpcore&lt;/a&gt;: Keeping with the pre-1.0 trend, &lt;code&gt;httpcore&lt;/code&gt; is an interesting option if you are building a library. It is low-level, so you can build your own abstractions on top of it. They explicitly recommend &lt;em&gt;not&lt;/em&gt; to use it unless you need a low-level library.&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://urllib3.readthedocs.io/en/latest/"&gt;urllib3&lt;/a&gt;: We should&lt;code&gt;urllib3&lt;/code&gt;, if only because it is the the underlying library that Requests and many others (including pip) are built on top of. While less user-friendly than some of the high-level libraries, urllib3 is powerful and battle-tested. If for some reason you need something with fewer abstractions than requests, it is a good option.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Making the most of API calls
&lt;/h2&gt;

&lt;p&gt;With Python's power in data processing and recent resurgence, thanks in part of the ML and data science communities, it is a great option for interacting with APIs. It is important to remember that even the most battle-tested and popular third-party APIs and services still suffer problems and outages. At Bearer, we're building tools to help manage these problems and better monitor your third-party APIs. &lt;a href="https://www.bearer.sh"&gt;Give Bearer a try&lt;/a&gt; today, and let us know what you think!&lt;/p&gt;

</description>
      <category>python</category>
      <category>tutorial</category>
      <category>api</category>
    </item>
  </channel>
</rss>
