<?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: Perry Donham</title>
    <description>The latest articles on DEV Community by Perry Donham (@perrydbucs).</description>
    <link>https://dev.to/perrydbucs</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%2F981%2Fbb4602b4-0ab5-4a09-afe4-c688f7e3300d.jpg</url>
      <title>DEV Community: Perry Donham</title>
      <link>https://dev.to/perrydbucs</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/perrydbucs"/>
    <language>en</language>
    <item>
      <title>To Whom It May Concern: Did you read my cover letter?</title>
      <dc:creator>Perry Donham</dc:creator>
      <pubDate>Sun, 01 Apr 2018 14:16:33 +0000</pubDate>
      <link>https://dev.to/perrydbucs/to-whom-it-may-concern-did-you-read-my-cover-letter-40ng</link>
      <guid>https://dev.to/perrydbucs/to-whom-it-may-concern-did-you-read-my-cover-letter-40ng</guid>
      <description>&lt;p&gt;As a college professor I get a lot of questions from students about applying for jobs and internships. Usually they are trying to land their first job after receiving a shiny new BSCS degree.&lt;/p&gt;

&lt;p&gt;Last week a student came up after class and asked if I'd comment on their cover letter. It was a full page long, started with a joke, and I couldn't make it past the first paragraph. My advice was to tear it up and write a three-sentence note that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Acknowledged that the recruiter / manager is busy&lt;/li&gt;
&lt;li&gt;Mentioned one specific thing the student found interesting about the company&lt;/li&gt;
&lt;li&gt;Thanked the recruiter / manager for their time&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I've been involved in the hiring process in the tech industry many times and have gone through literally thousands of resumes. I never read cover letters. My points to the student were:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The recruiter just wants to get through the stack; they aren't reading your cover letter&lt;/li&gt;
&lt;li&gt;You don't know the recruiter, and so any attempt to 'connect' with them is wasted and can come across as disingenuous&lt;/li&gt;
&lt;li&gt;Spend the time you would have spent on the letter making your resume visually effective; you have only 3 or 4 seconds to grab the reader's attention with your most important point&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I'm curious to hear what other folks think about cover letters, especially those who are actively involved in the hiring process. Do you read them? Do they affect your decisions?&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>career</category>
    </item>
    <item>
      <title>Using JWTs for Authentication in RESTful Applications</title>
      <dc:creator>Perry Donham</dc:creator>
      <pubDate>Fri, 29 Dec 2017 02:14:18 +0000</pubDate>
      <link>https://dev.to/perrydbucs/using-jwts-for-authentication-in-restful-applications-55hc</link>
      <guid>https://dev.to/perrydbucs/using-jwts-for-authentication-in-restful-applications-55hc</guid>
      <description>

&lt;h2&gt;The problem&lt;/h2&gt;

&lt;p&gt;Applications built using the MEAN stack typically use Node, MongoDB and Express on the back end to implement business logic fronted by a RESTful interface. Most of the work is done on the back end, and Angular serves as an enhanced view in the MVC  (model-view-controller) pattern. Keeping business rules and logic on the back end means that the application is view-agnostic; switching from Angular to React or straight jQuery or PHP should result in the same functionality.&lt;/p&gt;

&lt;p&gt;It's often the case that we need to protect some back-end routes, making them available only to authenticated users. The challenge is that our back-end services should be stateless, which means that we need a way for front-end code to provide proof of authentication at each request. At the same time, we can't trust any front-end code, since it is out of our control. We need an irrefutable mechanism for proving authentication that is entirely managed on the back end. We also want the mechanism to be out of the control of the client code, and done in such a way that it would be difficult or impossible to spoof.&lt;/p&gt;

&lt;h2&gt;The solution&lt;/h2&gt;

&lt;p&gt;JSON Web Tokens (JWTs) are a good solution for these requirements. The token is basically a JavaScript object in three parts:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;A &lt;em&gt;header&lt;/em&gt; that contains information about the algorithms used to generate the token&lt;/li&gt;
    &lt;li&gt;A &lt;em&gt;body&lt;/em&gt; with one or more claims&lt;/li&gt;
    &lt;li&gt;A cryptographic &lt;em&gt;signature&lt;/em&gt; based on the header and body&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;JWTs are formally described in &lt;a href="https://tools.ietf.org/html/rfc7519"&gt;RFC7519&lt;/a&gt;. There's nothing inherently authentication-y about them -- they are a mechanism to encapsulate and transmit data between two parties that ensures the integrity of the information. We can leverage this to give clients a way to prove their status without involving the client at all. Here's the flow:&lt;/p&gt;

&lt;ol&gt;
    &lt;li&gt;Client authenticates with the server (or via a third-party such as an OAuth provider)&lt;/li&gt;
    &lt;li&gt;Server creates a signed JWT describing authentication status and authorized roles using a secret that only the server knows&lt;/li&gt;
    &lt;li&gt;Server returns JWT to client in a session cookie marked &lt;em&gt;httpOnly&lt;/em&gt;
&lt;/li&gt;
    &lt;li&gt;At each request the client automatically sends the cookie and the enclosed JWT to the server&lt;/li&gt;
    &lt;li&gt;Server validates the JWT on each request and decides whether to allow client access to protected resources, returning either the requeseted resource or an error status&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Using a cookie to transmit the JWT provides a simple, automated way to pass the token back and forth between the client and the server and also gives the server control over the lifecycle of the cookie. Marking the cookie &lt;em&gt;httpOnly&lt;/em&gt; means that it is unavailable to client functions. And, since the token is signed using a secret known only to the server, it is difficult or impossible to spoof the claims in the token.&lt;/p&gt;

&lt;p&gt;The implementation discussed in this article uses a simple hash-based signing method. The header and body of the JWT are Base64 encoded, and then the encoded header and body, along with a server-side secret, are hashed to produce a signature. Another option is to use a public/private key pair to sign and verify the JWT. In the example, the JWT is handled only on the server, and so there's no benefit to using a signing key.&lt;/p&gt;

&lt;h2&gt;JWT authorization in code&lt;/h2&gt;

&lt;p&gt;Let's take a look at some code that implements our workflow. The application that I'm using in the following examples relies on third-party OAuth authentication from Twitter, and minimal profile information is held over for a user from session to session. The Twitter access token returned after a successful authentication is used as a key to a user record in a mongoDB database. The token exists until the user logs out or the user re-authenticates after having closed the browser window (thus invalidating the session cookie containing the JWT). Note that I've simplified error handling for readability.&lt;/p&gt;

&lt;h3&gt;Dependencies&lt;/h3&gt;

&lt;p&gt;Two convenience packages are used in the following code examples:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;cookie-parser - Express middleware to simplify cookie handling&lt;/li&gt;
    &lt;li&gt;jsonwebtoken - abstracts signing and validation of JWTs, based on the node-jws package&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I also use Mongoose as a layer on top of mongoDB; it provides ODM via schemas and also several handy query methods.&lt;/p&gt;

&lt;h3&gt;Creating the JWT and placing in in a session cookie&lt;/h3&gt;

&lt;p&gt;Once authentication with Twitter completes, Twitter invokes a callback method on the application, passing back an access token and secret, and information about the user such as their Twitter ID and screen name (passed in the &lt;em&gt;results&lt;/em&gt; object). Relevant information about the user is stored in a database document:&lt;/p&gt;

&lt;pre&gt;User.findOneAndUpdate( {twitterID: twitterID},
 {
     twitterID: twitterID,
     name: results.screen_name,
     username: results.screen_name,
     twitterAccessToken: oauth_access_token,
     twitterAccessTokenSecret: oauth_access_token_secret
 },
 {'upsert': 'true'},
 function (err, result) {
     if (err) {
     console.log(err)
 }
 else {
     console.log("Updated", results.screen_name, "in database.")
 }
})
&lt;/pre&gt;

&lt;p&gt;The &lt;em&gt;upsert&lt;/em&gt; option directs mongoDB to create a document if it not present, otherwise it updates an existing document.&lt;/p&gt;

&lt;p&gt;Next, a JWT is assembled. The &lt;em&gt;jsonwebtoken&lt;/em&gt; package takes care of creating the header of the JWT, so we just fill in the body with the Twitter access token. It is the access token that we'll use to find the user in the database during authorization checks.&lt;/p&gt;

&lt;pre&gt;const jwtPayload = {
     twitterAccessToken: oauth_access_token
 }&lt;/pre&gt;

&lt;p&gt;The JWT is then signed.&lt;/p&gt;

&lt;pre&gt; const authJwtToken = jwt.sign(jwtPayload, jwtConfig.jwtSecret)&lt;/pre&gt;

&lt;p&gt;&lt;em&gt;jwtSecret&lt;/em&gt; is a string, and can be either a single value used for all users (as it is in this application) or a per-user value, in which case it must be stored along with the user record. A strategy for per-user secrets might be to use the OAuth access token secret returned by Twitter, although it introduces a small risk if the response from Twitter has been intercepted. A concatenation of the Twitter secret and a server secret would be a good option. The secret is used during validation of the signature when authorizing a client's request. Since it is stored on the server and never shared with the client, it is an effective way to verify that a token presented by a client was in fact signed by the server.&lt;/p&gt;

&lt;p&gt;The signed JWT is placed on a cookie. The cookie is marked &lt;em&gt;httpOnly&lt;/em&gt;, which restricts visibility on the client, and its expiration time is set to zero, making it a session-only cookie.&lt;/p&gt;

&lt;pre&gt;const cookieOptions = {
  httpOnly: true,
  expires: 0 
 }
 res.cookie('twitterAccessJwt', authJwtToken, cookieOptions)&lt;/pre&gt;

&lt;p&gt;Keep in mind that the cookie isn't visible to client-side code, so if you need a way to tell the client that the user is authenticated you'll want to add a flag to another, visible, cookie or otherwise pass data indicating authorization status back to the client.&lt;/p&gt;

&lt;h3&gt;Why a cookie &lt;em&gt;and&lt;/em&gt; a JWT?&lt;/h3&gt;

&lt;p&gt;We certainly could send the JWT back to the client as an ordinary object, and use the data it contains to drive client-side code. The payload is not encrypted, just Base64 encoded, and would thus be accessible to the client. It could be placed on the session for transport to and from the server, though this would have to be done on each request-response pair, on both the sever and the client, since this kind of session variable is not automatically passed back and forth.&lt;/p&gt;

&lt;p&gt;Cookies, on the other hand, &lt;em&gt;are&lt;/em&gt; automatically sent with each request and each response without any additional action. As long as the cookie hasn't expired or been deleted it will accompany each request back to the server. Further, marking the cookie &lt;em&gt;httpOnly&lt;/em&gt; hides it from client-side code, reducing the opportunity for it to be tampered with. This particular cookie is only used for authorization, so there's no need for the client to see it or interact with it.&lt;/p&gt;

&lt;h2&gt;Authorizing requests&lt;/h2&gt;

&lt;p&gt;At this point we've handed the client an authorization token that has been signed by the server. Each time the client makes a request to the back-end API, the token is passed inside a session cookie. Remember, the server is stateless, and so we need to verify the authenticity of the token on each request. There are two steps in the process:&lt;/p&gt;

&lt;ol&gt;
    &lt;li&gt;Check the signature on the token to prove that the token hasn't been tampered with&lt;/li&gt;
    &lt;li&gt;Verify that the user associated with the token is in our database&lt;/li&gt;
    &lt;li&gt;[optionally] Retrieve a set of roles for this user&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Simply checking the signature isn't enough -- that just tells us that the information in the token hasn't been tampered with since it left the server, not that the owner is who they say they are; an attacker might have stolen the cookie or otherwise intercepted it. The second step give us some assurance that the user is valid; the database entry was created inside a Twitter OAuth callback, which means that the user had just authenticated with Twitter. The token itself is in a session cookie, meaning that it is not persisted on the client side (it is held in memory, not on disk) and that has the &lt;em&gt;httpOnly&lt;/em&gt; flag set, which limits its visibility on the client.&lt;/p&gt;

&lt;p&gt;In Express, we can create a middleware function that validates protected requests. Not all requests need such protection; there might be parts of the application that are open to non-logged-in users. A restricted-access POST request on the URI &lt;em&gt;/db&lt;/em&gt; looks like this:&lt;/p&gt;

&lt;pre&gt;&lt;span&gt;// POST Create a new user (only available to logged-in users)
&lt;/span&gt;&lt;span&gt;//
&lt;/span&gt;&lt;span&gt;router&lt;/span&gt;.&lt;span&gt;post&lt;/span&gt;(&lt;span&gt;'/db'&lt;/span&gt;, &lt;span&gt;checkAuthorization&lt;/span&gt;, &lt;span&gt;function &lt;/span&gt;(req, res, next) {
...
}&lt;/pre&gt;

&lt;p&gt;In this route, &lt;i&gt;checkAuthorization&lt;/i&gt; is a function that validates the JWT sent by the client:&lt;/p&gt;

&lt;pre&gt;&lt;span&gt;const &lt;/span&gt;&lt;span&gt;checkAuthorization &lt;/span&gt;= &lt;span&gt;function &lt;/span&gt;(req, res, next) {

    &lt;span&gt;// 1. See if there is a token on the request...if not, reject immediately
&lt;/span&gt;&lt;span&gt;    //
&lt;/span&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;const &lt;/span&gt;&lt;span&gt;userJWT &lt;/span&gt;= req.&lt;span&gt;cookies&lt;/span&gt;.twitterAccessJwt
    &lt;span&gt;if &lt;/span&gt;(!&lt;span&gt;userJWT&lt;/span&gt;) {
        res.&lt;span&gt;send&lt;/span&gt;(&lt;span&gt;401&lt;/span&gt;, &lt;span&gt;'Invalid or missing authorization token'&lt;/span&gt;)
    }&lt;/pre&gt;

&lt;pre&gt;    &lt;span&gt;//2. There's a token; see if it is a valid one and retrieve the payload
&lt;/span&gt;&lt;span&gt;    //
&lt;/span&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;else &lt;/span&gt;{
        &lt;span&gt;const &lt;/span&gt;&lt;span&gt;userJWTPayload &lt;/span&gt;= &lt;span&gt;jwt&lt;/span&gt;.&lt;span&gt;verify&lt;/span&gt;(&lt;span&gt;userJWT&lt;/span&gt;, &lt;span&gt;jwtConfig&lt;/span&gt;.&lt;span&gt;jwtSecret&lt;/span&gt;)
        &lt;span&gt;if &lt;/span&gt;(!&lt;span&gt;userJWTPayload&lt;/span&gt;) {
            &lt;span&gt;//Kill the token since it is invalid
&lt;/span&gt;&lt;span&gt;            //
&lt;/span&gt;&lt;span&gt;            &lt;/span&gt;res.&lt;span&gt;clearCookie&lt;/span&gt;(&lt;span&gt;'twitterAccessJwt'&lt;/span&gt;)
            res.&lt;span&gt;send&lt;/span&gt;(&lt;span&gt;401&lt;/span&gt;, &lt;span&gt;'Invalid or missing authorization token'&lt;/span&gt;)
        }
        &lt;span&gt;else &lt;/span&gt;{&lt;/pre&gt;

&lt;pre&gt;            &lt;span&gt;//3. There's a valid token...see if it is one we have in the db as a logged-in user
&lt;/span&gt;&lt;span&gt;            //
&lt;/span&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;User&lt;/span&gt;.&lt;span&gt;findOne&lt;/span&gt;({&lt;span&gt;'twitterAccessToken'&lt;/span&gt;: &lt;span&gt;userJWTPayload&lt;/span&gt;.&lt;span&gt;twitterAccessToken&lt;/span&gt;})
                .&lt;span&gt;then&lt;/span&gt;(&lt;span&gt;function &lt;/span&gt;(user) {
                    &lt;span&gt;if &lt;/span&gt;(!user) {
                        res.&lt;span&gt;send&lt;/span&gt;(&lt;span&gt;401&lt;/span&gt;, &lt;span&gt;'User not currently logged in'&lt;/span&gt;)
                    }
                    &lt;span&gt;else &lt;/span&gt;{
                        &lt;span&gt;console&lt;/span&gt;.&lt;span&gt;log&lt;/span&gt;(&lt;span&gt;'Valid user:'&lt;/span&gt;, user.&lt;span&gt;name&lt;/span&gt;)
                        next()
                    }

                })
        }
    }
}&lt;/pre&gt;

&lt;p&gt;Assuming that the authorization cookie exists (Step 1), it is then checked for a valid signature using the secret stored on the server (Step 2). &lt;em&gt;jwt.verify&lt;/em&gt; returns the JWT payload object if the signature is valid, or null if it is not. A missing or invalid cookie or JWT results in a 401 (Not Authorized) response to the client, and in the case of an invalid JWT the cookie itself is deleted.&lt;/p&gt;

&lt;p&gt;If steps 1 and 2 are valid, we check the database to see if we have a record of the access token carried on the JWT, using the Twitter access token as the key. If a record is present it is a good indication that the client is authorized, and the call to &lt;em&gt;next()&lt;/em&gt; at the end of Step 3 passes control to the next function in the middleware chain, which is in this case the rest of the POST route.&lt;/p&gt;

&lt;h2&gt;Logging the user out&lt;/h2&gt;

&lt;p&gt;If the user explicitly logs out, a back-end route is called to do the work:&lt;/p&gt;

&lt;pre&gt;&lt;span&gt;//This route logs the user out:
&lt;/span&gt;&lt;span&gt;//1. Delete the cookie
&lt;/span&gt;&lt;span&gt;//2. Delete the access key and secret from the user record in mongo
&lt;/span&gt;&lt;span&gt;//
&lt;/span&gt;&lt;span&gt;router&lt;/span&gt;.&lt;span&gt;get&lt;/span&gt;(&lt;span&gt;'/logout'&lt;/span&gt;, checkAuthorization, &lt;span&gt;function &lt;/span&gt;(req, res, next) {
    &lt;span&gt;const &lt;/span&gt;&lt;span&gt;userJWT &lt;/span&gt;= req.&lt;span&gt;cookies&lt;/span&gt;.twitterAccessJwt
    &lt;span&gt;const &lt;/span&gt;&lt;span&gt;userJWTPayload &lt;/span&gt;= &lt;span&gt;jwt&lt;/span&gt;.&lt;span&gt;verify&lt;/span&gt;(&lt;span&gt;userJWT&lt;/span&gt;, &lt;span&gt;jwtConfig&lt;/span&gt;.&lt;span&gt;jwtSecret&lt;/span&gt;)

    res.&lt;span&gt;clearCookie&lt;/span&gt;(&lt;span&gt;'twitterAccessJwt'&lt;/span&gt;)
    &lt;span&gt;User&lt;/span&gt;.&lt;span&gt;findOneAndUpdate&lt;/span&gt;({&lt;span&gt;twitterAccessToken&lt;/span&gt;: &lt;span&gt;userJWTPayload&lt;/span&gt;.&lt;span&gt;twitterAccessToken&lt;/span&gt;},
        {
            &lt;span&gt;twitterAccessToken&lt;/span&gt;: &lt;span&gt;null&lt;/span&gt;,
            &lt;span&gt;twitterAccessTokenSecret&lt;/span&gt;: &lt;span&gt;null
&lt;/span&gt;&lt;span&gt;        &lt;/span&gt;},
        &lt;span&gt;function &lt;/span&gt;(err, result) {
            &lt;span&gt;if &lt;/span&gt;(err) {
                &lt;span&gt;console&lt;/span&gt;.&lt;span&gt;log&lt;/span&gt;(err)
            }
            &lt;span&gt;else &lt;/span&gt;{
                &lt;span&gt;console&lt;/span&gt;.&lt;span&gt;log&lt;/span&gt;(&lt;span&gt;"Deleted access token for"&lt;/span&gt;, result.&lt;span&gt;name&lt;/span&gt;)
            }
            res.&lt;span&gt;render&lt;/span&gt;(&lt;span&gt;'twitterAccount'&lt;/span&gt;, {&lt;span&gt;loggedIn&lt;/span&gt;: &lt;span&gt;false&lt;/span&gt;})
        })

})&lt;/pre&gt;

&lt;p&gt;We again check to see if the user is logged in, since we need the validated contents of the JWT in order to update the user's database record.&lt;/p&gt;

&lt;p&gt;If the user simply closes the browser tab without logging out, the session cookie containing the JWT will be removed on the client. On next access the JWT will not validate in checkAuthorization and the user will be directed to the login page; successful login will update the access token and associated secret in the database.&lt;/p&gt;

&lt;h2&gt;Comments&lt;/h2&gt;

&lt;p&gt;In no particular order...&lt;/p&gt;

&lt;p&gt;Some services set short expiration times on access tokens, and provide a method to exchange a 'refresh' token for a new access token. In that case an extra step would be necessary in order to update the token stored on the session cookie. Since access to third-party services are handled on the server, this would be transparent to the client.&lt;/p&gt;

&lt;p&gt;This application only has one role: a logged-in user. For apps that require several roles, they should be stored in the database and retrieved on each request.&lt;/p&gt;

&lt;p&gt;An architecture question comes up in relation to checkAuthorization. The question is, who should be responsible for handling an invalid user? In practical terms, should &lt;em&gt;checkAuthorization&lt;/em&gt; return a boolean that can be used by each protecte route? Having &lt;em&gt;checkAuthorization&lt;/em&gt; handle invalid cases centralizes this behavior, but at the expense of losing flexibility in the routes. I've leaned both way on this...an unauthorized user is unauthorized, period, and so it makes sense to handle that function in checkAuthorization; however, there might be a use case in which a route passes back a subset of data for unauthenticated users, or adds an extra bit of information for authorized users. For this particular example the centralized version works fine, but you'll want to evaluate the approach based on your won use cases.&lt;/p&gt;

&lt;p&gt;The routes in this example simply render a Pug template that displays a user's Twitter accoun information, and a flag (loggedIn) is used to show and hide UI components. A more complex app will need a cleaner way of letting the client know the status of a user.&lt;/p&gt;

&lt;p&gt;A gist with sampe code is availabe at &lt;a href="https://gist.github.com/pdonham/bdb91ed5f7d87c5f79a74d3b4d978d3d"&gt;gist:bdb91ed5f7d87c5f79a74d3b4d978d3d&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;i&gt;Originally posted &lt;a href="http://sites.bu.edu/perryd/?p=259&amp;amp;preview=true"&gt;on my blog &lt;/a&gt;at Boston University&lt;/i&gt;&lt;/p&gt;


</description>
      <category>javascript</category>
      <category>node</category>
    </item>
    <item>
      <title>Composing the results of nested asynchronous calls in Javascript using async.waterfall and ES6 Promises</title>
      <dc:creator>Perry Donham</dc:creator>
      <pubDate>Wed, 12 Jul 2017 19:21:22 +0000</pubDate>
      <link>https://dev.to/perrydbucs/composing-the-results-of-nested-asynchronous-calls-in-javascript-using-asyncwaterfall-and-es6-promises</link>
      <guid>https://dev.to/perrydbucs/composing-the-results-of-nested-asynchronous-calls-in-javascript-using-asyncwaterfall-and-es6-promises</guid>
      <description>&lt;p&gt;&lt;i&gt;I posted this recently &lt;a href="http://sites.bu.edu/perryd"&gt;on my blog&lt;/a&gt; and thought I'd share it here. I taught a course this summer in MEAN application development and observed that many of my students had a tough time working in an asynchronous environment (most had not done any Javascript coding). This article was my attempt to both help my students with some patterns and to help solidify the topic in my own head. I welcome constructive criticism, especially if I'm off track!&lt;br&gt;
&lt;/i&gt;&lt;/p&gt;

&lt;h2&gt;Grokking asynchronicity&lt;/h2&gt;

&lt;p&gt;One ofÂ the toughest things to get your head around in Javascript is how to handle nested asynchronous calls, especially when aÂ function depends on the result of a preceding one. I see this quite a bit in my software engineering course where teams are required to synthesize new information from two distinct third-party data sources. The pattern is to look something up that returns a collection, and then look something else up for each ofÂ the members in the collection.&lt;/p&gt;

&lt;p&gt;There are multiple approaches to this problem, but most rely on Javascript Promises, either from a third-party library in ES5 and earlier or ES6's built-in Promises. In this article we'll use both by using ES6 native Promises and the async.js package. This isn't a discussion of ES6 Promises per se, but it might help you get to the point of understanding them.&lt;/p&gt;

&lt;p&gt;The file discussed here is intended to be mounted on a route in a Node/Express application:&lt;/p&gt;

&lt;pre&gt;&lt;span&gt;//From app.js
const &lt;/span&gt;&lt;span&gt;rp &lt;/span&gt;= &lt;span&gt;require&lt;/span&gt;(&lt;span&gt;'./routes/request-promises'&lt;/span&gt;)
&lt;span&gt;app&lt;/span&gt;.&lt;span&gt;use&lt;/span&gt;(&lt;span&gt;'/rp'&lt;/span&gt;, &lt;span&gt;rp&lt;/span&gt;)&lt;/pre&gt;

&lt;p&gt;[Unfortunately the Wordpress implementation used on the BU blog does a horrific job displaying code, so the code snippets below are images for the bulk of the discussion. The complete file is available at the bottom of the post.]&lt;/p&gt;

&lt;p&gt;The route hereÂ usesÂ two APIs:&lt;br&gt;
&lt;em&gt;&lt;a href="https://weathers.co"&gt;https://weathers.co&lt;/a&gt;&lt;/em&gt; for current weather in 3 cities, and&lt;br&gt;
&lt;em&gt;&lt;a href="https://api.github.com/search/repositories?q=&amp;lt;term"&gt;https://api.github.com/search/repositories?q=&amp;amp;lt;term&lt;/a&gt;&amp;gt;&lt;/em&gt; to search GitHub repos forÂ the 'hottest' city.&lt;/p&gt;

&lt;p&gt;In ourÂ example we'll grab weather for 3 cities, pick the hottest one,Â then hit GitHub with a search for repos that have that city's name. It's a bit contrivedÂ but we just want to demonstrate using the results of one API call to populate a second when all of them are asynch.&lt;/p&gt;

&lt;p&gt;There are two packages (apart from Express) used:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vIYbGkvc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/pkf9zy7eoz6g4oklmhim.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vIYbGkvc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/pkf9zy7eoz6g4oklmhim.png" alt="packages"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The first is a reduced-size packaging of the standard &lt;em&gt;request-promise&lt;/em&gt; package; we don't need all of the features of the larger library. &lt;em&gt;request-promise&lt;/em&gt; itself is a wrapper that adds Promises to the standard &lt;em&gt;request&lt;/em&gt; package used to make network calls, for example to an HTTP endpoint.&lt;/p&gt;

&lt;p&gt;There's only one route in this module, a GET on the top-level URL. In the snippet above, this router is mounted at '/rp', and so the complete URL path is &lt;a href="http://localhost:3000/rp"&gt;http://localhost:3000/rp&lt;/a&gt; (assuming the server is set to listen to port 3000).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--aSPtv8E_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/ap7psiptu2a4bed5c4f0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--aSPtv8E_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/ap7psiptu2a4bed5c4f0.png" alt="route"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On line 50 the &lt;em&gt;async.waterfall&lt;/em&gt; method is used to create a chain of functions that will execute in turn. Each function returns a Promise, and so the next function in line waits until the preceding function's Promise is resolved. We need this because each function provides data that the following function will use in some way. That data is providedÂ to each function in turn along with a callback, which is the next function in the waterfall.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;async.waterfall&lt;/em&gt; takes two parameters in this implementation: An array of functions to call in order, and a final function (&lt;em&gt;renderTable &lt;/em&gt;on line 51)Â to execute last. A small side note: The final function can be anonymous, but when debugging a big application it can be tough to figure out exactly which anonymous function out of potentially hundreds is causing a problem. Naming those functions helps immensely when debugging!&lt;/p&gt;

&lt;h3&gt;getCityTemperatures&lt;/h3&gt;

&lt;p&gt;The first function in the waterfall, &lt;em&gt;getCityTemperatures&lt;/em&gt;, calls the weathers.co API for each city in a hardcoded array. This is theÂ first function in the waterfall and so it receives only one param, the callback (cb).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uDjK6hBi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/ueptjzehhnq9schcqkr8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uDjK6hBi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/ueptjzehhnq9schcqkr8.png" alt="getCityTemperatures"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is the most interesting function of the three because it has to do an API call forÂ each city in the &lt;em&gt;cities&lt;/em&gt; array, and they all are asynchronous calls. We can't return from the functionÂ until all of the city weather has been collected.&lt;/p&gt;

&lt;p&gt;In each API call, once the current temperature is known it is plugged into the city's objectÂ in the &lt;em&gt;cities&lt;/em&gt; array. (Note that weathers.co doesn't always return the actual current temperature.Â Often it is a cached value.)Â The technique here is to create a Promise that encompasses the API calls on line 83. This Promise represents the entire function, and it won't be resolved until all of the city weather has been collected.&lt;/p&gt;

&lt;p&gt;A secondÂ Promise is set up in the local function &lt;em&gt;getWeather&lt;/em&gt; on line 91,Â and that's the one that handlesÂ each individual city's API call. &lt;em&gt;request.get()&lt;/em&gt; itself returns a Promise on line 92 (because we are using the request-promise-lite package), and so we make the &lt;em&gt;request.get()&lt;/em&gt; and followÂ it with a then() which will run when the API call returns. The resolve() at line 96Â gets us out of this inner Promise and on to the next one.&lt;/p&gt;

&lt;p&gt;Note that we don't yet execute &lt;em&gt;getWeather()&lt;/em&gt;,Â we're just &lt;em&gt;defining&lt;/em&gt; it here. Line 109 uses the &lt;em&gt;Array.map&lt;/em&gt; method to return an array that has three functions in it. Each function has one of the city objects passed into it, and each returns a Promise (as defined on line 91). That &lt;em&gt;cityPromises&lt;/em&gt; array looks like&lt;/p&gt;

&lt;pre&gt;[getWeather({name: 'Miami', temperature: null}),Â &lt;span&gt;getWeather({name: 'Atlanta', temperature: null}),Â &lt;/span&gt;&lt;span&gt;getWeather({name: 'Boston', temperature: null})]&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;after line 109 completes.&lt;/p&gt;

&lt;p&gt;We &lt;em&gt;still&lt;/em&gt; haven't executed anything. The mapping in line 109 sets us up to use the &lt;em&gt;Promise.all( )&lt;/em&gt; method from the ES6 native Promise library in line 121, which only resolves when all of the Promises in its input array have resolved. It's a bit like the async.waterfall( ) call from line 50, but in this case order doesn't matter. If any of the Promises reject, the entire Promise.all( ) structure rejects at that moment, even if there are outstanding unresolved Promises.&lt;/p&gt;

&lt;p&gt;Once all of the Promises have resolved (meaning that each city's weather has been recorded), the then( ) in line 122 executes, and calls the passed-in callback with the now-complete array of cities and temperatures. The &lt;em&gt;null&lt;/em&gt; value handed to the callback is interpreted as an error object.&lt;/p&gt;

&lt;p&gt;Of interest here is that Promise.all( ) is, practically speaking, running the requests in parallel.&lt;/p&gt;

&lt;h3&gt;getHottestCity&lt;/h3&gt;

&lt;p&gt;The next function in the chain, getHottestCity, simply finds the largest temperature in the array of cities and returns that city's object to the next function in the waterfall. This is synchronous code and so doesn't require a Promise.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZTPBlU8R--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/vw2wlcc9hu28ezwwtgup.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZTPBlU8R--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/vw2wlcc9hu28ezwwtgup.png" alt="getHottestCity"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Line 140 creates a slice with just the temperatures from the &lt;em&gt;cities&lt;/em&gt; array and calls &lt;em&gt;Math.max( )&lt;/em&gt; to determine the largest value. Line 143 then looks for the hottest temperature in the original cities array and returns the corresponding object. Both of these lines use the ES6 way of defining functions with fat-arrow notation (=&amp;gt;), and line 140 uses the new spread operator.&lt;/p&gt;

&lt;p&gt;Once the 'hot' city has been determined it is passed to the next function in the waterfall in line 148. Here again, the &lt;em&gt;null&lt;/em&gt; is in the place of an error object.&lt;/p&gt;

&lt;h3&gt;findGithubRepos&lt;/h3&gt;

&lt;p&gt;The next-to-last function in the waterfall searches Github for projects that include the name of the 'hot' city discovered earlier. The User-Agent header in line 167 is required by the Github search API -- you can change it to any string that you like.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--k4JD1VYg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/v068wbtybka21tm6vkl3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--k4JD1VYg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/v068wbtybka21tm6vkl3.png" alt="findGithubRepos"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The API call in line 165 uses &lt;em&gt;request-promise&lt;/em&gt; (from line 29) and so returns a Promise. Once the Promise is resolved, the &lt;em&gt;then( )&lt;/em&gt; function builds an array of objects from some of the data returned.&lt;/p&gt;

&lt;p&gt;In line 180 the completed array of items is passed to the next function in the waterfall along with the original 'hot' city object.&lt;/p&gt;

&lt;h3&gt;The final function&lt;/h3&gt;

&lt;p&gt;The last function to execute simply takes the results of our waterfall and renders a Pug page on line 57.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zg5Ul4B_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/njnbfzc6wk00bny8vu5f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zg5Ul4B_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/njnbfzc6wk00bny8vu5f.png" alt="waterfall"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here's a &lt;a href="https://gist.github.com/pdonham/8d2c7e0ccd482150a6877b5075794b23"&gt;link to the complete file&lt;/a&gt;. If you have questions or corrections, leave a comment!&lt;/p&gt;

</description>
      <category>node</category>
      <category>es6</category>
      <category>asynchronous</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
