<?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: Graham Cox</title>
    <description>The latest articles on DEV Community by Graham Cox (@grahamcox82).</description>
    <link>https://dev.to/grahamcox82</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%2F937%2F6Cz4rVt2.jpg</url>
      <title>DEV Community: Graham Cox</title>
      <link>https://dev.to/grahamcox82</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/grahamcox82"/>
    <language>en</language>
    <item>
      <title>A Hypermedia powered Authentication flow</title>
      <dc:creator>Graham Cox</dc:creator>
      <pubDate>Sun, 13 Dec 2020 14:40:14 +0000</pubDate>
      <link>https://dev.to/grahamcox82/a-hypermedia-powered-authentication-flow-263l</link>
      <guid>https://dev.to/grahamcox82/a-hypermedia-powered-authentication-flow-263l</guid>
      <description>&lt;p&gt;Hypermedia and REST are big things right now. By choosing to write your APIs in a way that follows the HTTP rules correctly you open a lot of doors to all sorts of behaviour, and by embracing hypermedia you allow the server to dictate to the client how things should behave, which in turn means that the server can change functionality and the client will have little or no changes to make to take advantage of it.&lt;/p&gt;

&lt;p&gt;Here I am going to demonstrate how a rich Hypermedia API could be built using &lt;a href="https://github.com/kevinswiber/siren"&gt;SIREN&lt;/a&gt; to allow for an authentication flow.&lt;/p&gt;

&lt;p&gt;Note that we are &lt;em&gt;not&lt;/em&gt; building an app here. There is no server nor client-side code for this, only a discussion of how the API could work.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is SIREN
&lt;/h2&gt;

&lt;p&gt;SIREN is a standard hypermedia format that allows us to return the data for our resource as well as metadata describing what we can do with it. This metadata consists of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Links to other resources. These typically are used for navigation or for links to non-hypermedia resources.&lt;/li&gt;
&lt;li&gt;Entities representing other hypermedia resources. These can either be just a link or else an actual representation of the resource.&lt;/li&gt;
&lt;li&gt;Actions that can be performed on the current resource.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These "actions" are the important detail here. If we have a client that is able to react correctly to SIREN responses, we will see how the server can indicate what actions need to be performed, what fields need to be captured and the client can just react accordingly.&lt;/p&gt;

&lt;h2&gt;
  
  
  API Requirements
&lt;/h2&gt;

&lt;p&gt;Our requirements here are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The user enters their username on the first screen.&lt;/li&gt;
&lt;li&gt;If the username is unknown then they are presented with a registration form to capture the required details.&lt;/li&gt;
&lt;li&gt;If the username is known then they are presented with an authentication form to capture the required details.&lt;/li&gt;
&lt;li&gt;If they have MFA enabled then the required details are different than if it's disabled. When MFA is enabled we need both the password and the authentication code from their app.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Username Screen
&lt;/h2&gt;

&lt;p&gt;When the client wants to allow authentication, it will first make a &lt;code&gt;GET&lt;/code&gt; request to &lt;code&gt;/authentication&lt;/code&gt;. (This will have been identified by a link from the API home page.) This response could look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"class"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"authentication"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"links"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"rel"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"self"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"href"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/authentication"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="s2"&gt;"actions"&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"authenticate"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Log In / Register"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"method"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"POST"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"href"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/authentication"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"application/x-www-form-urlencoded"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"fields"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"username"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Username"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"text"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This looks complicated, so let's work through it.&lt;/p&gt;

&lt;p&gt;What we have here is a link indicating what the "self" link is for this resource - this is literally the link to the resource itself. &lt;/p&gt;

&lt;p&gt;We also define a single action with the name "authenticate". This is our submission for this resource, and indicates that we are performing authentication. This action has a title that can be used in the UI if desired, a single field for the username, and indicates that submissions should be a &lt;code&gt;POST&lt;/code&gt; to &lt;code&gt;/authentication&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Already this gives us enough information to build the first screen needed to start authentication.&lt;/p&gt;

&lt;h2&gt;
  
  
  Registration
&lt;/h2&gt;

&lt;p&gt;When the above form is submitted, the server will determine if the username is known or not. If it's not known then a new user registration is needed. This could be indicated with the following API response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"class"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"authentication"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"links"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"rel"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"self"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"href"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/authentication"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="s2"&gt;"actions"&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"register"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Register"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"method"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"POST"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"href"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/register"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"application/x-www-form-urlencoded"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"fields"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"username"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"hidden"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"newUser"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Email Address"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"email"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"password"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Password"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"password"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our action looks more complicated here, but actually it's only an extension of what we saw before. We've got a different &lt;code&gt;href&lt;/code&gt; to send the fields to, and we've now got three fields. The first is a hidden field containing the username that was entered on the first screen. The other two are the fields that we need to capture to register the user - their email address and desired password.&lt;/p&gt;

&lt;p&gt;We can render this using the exact same rules as the first one, and suddenly we'll get a registration form instead, just by following the API response.&lt;/p&gt;

&lt;h2&gt;
  
  
  Simple Authentication
&lt;/h2&gt;

&lt;p&gt;If the server determined that the username entered was already known then the API response could instead be something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"class"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"authentication"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"links"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"rel"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"self"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"href"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/authentication"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="s2"&gt;"actions"&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"authenticate"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Log In"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"method"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"POST"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"href"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/authenticate"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"application/x-www-form-urlencoded"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"fields"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"username"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"hidden"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"existingUser"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"password"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Password"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"password"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This actually looks very similar to the registration response. We have different values for the title and &lt;code&gt;href&lt;/code&gt;, and we only need to capture the password in addition to the already known username.&lt;/p&gt;

&lt;h2&gt;
  
  
  MFA Authentication
&lt;/h2&gt;

&lt;p&gt;What about if the user has multi-factor authentication enabled? This is actually easily handled now - we simply return an additional field in our response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"class"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"authentication"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"links"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"rel"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"self"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"href"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/authentication"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="s2"&gt;"actions"&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"authenticate"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Log In"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"method"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"POST"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"href"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/authenticate"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"application/x-www-form-urlencoded"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"fields"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"username"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"hidden"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"existingUser"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"password"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Password"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"password"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"code"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Auth Code"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"text"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;em&gt;only&lt;/em&gt; difference here is the addition of the &lt;code&gt;code&lt;/code&gt; field in our response. This will indicate to the client that they need to capture an additional value when logging in. This will then be passed to the server which will be able to check both the password and the authentication code and act accordingly.&lt;/p&gt;

&lt;h1&gt;
  
  
  Summary
&lt;/h1&gt;

&lt;p&gt;Here we can see that the only changes we've had to make are in the API response indicating which actions are available, and the client can automatically display the correct forms to implement both a user registration and authentication flow.&lt;/p&gt;

&lt;p&gt;This also means that we can start to capture different values for user registration by only changing the API response, and having the client automatically react to it. &lt;/p&gt;

&lt;p&gt;This gives a huge amount of flexibility - suddenly we can have clients that build themselves correctly based on what the server instructs them, so changes propagate automatically without needing to update both the server and client in sync with each other.&lt;/p&gt;

&lt;p&gt;Of particular note are the APIs that we've &lt;em&gt;not&lt;/em&gt; written. We've not had to have any API to look up if a username exists, nor any API to determine if a user is partaking in multi-factor authentication. The API response from submitting the username gives us all of this in one simple package.&lt;/p&gt;

&lt;p&gt;This also means that the client isn't making any decisions on how to work. There is no need for the client to determine which form to display, nor which fields to display. It just gets the response from the server and displays what it's told to. Which puts all of the complexity in one single place.&lt;/p&gt;

</description>
      <category>rest</category>
      <category>siren</category>
      <category>hypermedia</category>
    </item>
    <item>
      <title>Hexagonal Architecture doesn't really work</title>
      <dc:creator>Graham Cox</dc:creator>
      <pubDate>Sat, 16 Nov 2019 15:10:07 +0000</pubDate>
      <link>https://dev.to/grahamcox82/hexagonal-architecture-doesn-t-really-work-cia</link>
      <guid>https://dev.to/grahamcox82/hexagonal-architecture-doesn-t-really-work-cia</guid>
      <description>&lt;p&gt;For various reasons, I've been reading a lot of late on Hexagonal Architecture / Ports and Adapters. On the face of it, this seems really neat. &lt;/p&gt;

&lt;p&gt;Basically, you define an inner domain, with the domain models, interfaces for all of the ports that the domain depends on - the driven ports, and interfaces for the ports that the domain exposes - the driving ports. The domain then also has a service that implements the driving ports on terms of the driven ports.&lt;/p&gt;

&lt;p&gt;The benefit here is that anything depending on the Driving ports needs know nothing about the internals, and anything implementing the Driven ports can be plugged in. This means, for example, we can plug the domain into a web server, a command line app or an Android app with no business logic changes. It also means we can plug in a Postgres database, or a DynamoDB database with no changes to the business logic.&lt;/p&gt;

&lt;p&gt;This all sounds really good. But does it work?&lt;/p&gt;

&lt;p&gt;My very first thought was about changing database technology, and the fact that different databases do different things. And specifically about text searching.&lt;/p&gt;

&lt;p&gt;If I decide to use Postgres then it has full text searching built in, so I only need one port and one adapter. If I decide to use DynamoDB then it does &lt;em&gt;not&lt;/em&gt; have support for text searching, so I would need a second port for a full text engine, and an adapter for CloudSearch.&lt;/p&gt;

&lt;p&gt;The problem here is that the choice of infrastructure defines the ports, and this is exactly &lt;em&gt;Not&lt;/em&gt; the point.&lt;/p&gt;

&lt;p&gt;The alternative is that we implement the DataStore and the TextSearch ports for Postgres, but have the TextSearch just do nothing when indexing documents. Except this is a waste of effort. Worse, it seems reasonable that the TextSearch port returns the ID of the matching records for the DataStore port to fetch, but if they're both the same database then this is a performance sink - it's two queries when one would suffice.&lt;/p&gt;

&lt;p&gt;So, unless someone can enlighten me (please!), it seems that this architecture is potentially very tied to the infrastructure decisions after all.&lt;/p&gt;

</description>
      <category>design</category>
      <category>architecture</category>
      <category>hexagonal</category>
    </item>
    <item>
      <title>Building a larger Serverless application - Part 3: Modular Monorepos</title>
      <dc:creator>Graham Cox</dc:creator>
      <pubDate>Thu, 17 Oct 2019 06:22:38 +0000</pubDate>
      <link>https://dev.to/grahamcox82/building-a-larger-serverless-application-part-3-modular-monorepos-3mon</link>
      <guid>https://dev.to/grahamcox82/building-a-larger-serverless-application-part-3-modular-monorepos-3mon</guid>
      <description>&lt;p&gt;I've decided that I'm using AWS, Serverless and Node.js for my actual code. Now to decide how to actually structure it.&lt;/p&gt;

&lt;p&gt;I want to keep distinct areas actually distinct from each other. Allow for a truly modular approach. I also want to use a single repository and not lots of them, because it's just easier for a single person or small team that way.&lt;/p&gt;

&lt;p&gt;Surprisingly, this is not easy.&lt;/p&gt;

&lt;p&gt;AWS CloudFormation - and thus AWS SAM, and thus Serverless - builds our infrastructure in Stacks. A single stack represents a single unit of infrastructure, and everything that goes with it. So this would be Lambdas, DynamoDB tables, Queues, IAM roles, everything. It also supports what are called Nested Stacks, where one stack is actually composed of others. &lt;/p&gt;

&lt;h2&gt;
  
  
  Why use Nested Stacks?
&lt;/h2&gt;

&lt;p&gt;One obvious question is - why should we use a nested stack? One of the benefits is that you can create and destroy the entire stack in one go. However, this isn't the real selling point.&lt;/p&gt;

&lt;p&gt;AWS has a hard limit of 200 resources in any single stack. A stack that contains a single Lambda attached to an API Gateway, and a single DynamoDB table will contain up to 13 of these resources. This means that we can have 15 such stacks until we run out. Nested stacks let us circumvent this because we can have a parent stack containing many nested stacks, each of which have this 200 resource limit. We can nest these as deep as we want too, so we can structure this however we want.&lt;/p&gt;

&lt;h2&gt;
  
  
  Shared API Gateways
&lt;/h2&gt;

&lt;p&gt;One obvious problem with multiple stacks is the URLs. The default behaviour would be that each stack has it's own API Gateway, and thus it's own URL. That is not helpful.&lt;/p&gt;

&lt;p&gt;However, we can solve this. AWS already lets us share resources between stacks as long as they belong to the same IAM user. Serverless lets us achieve this as well.&lt;/p&gt;

&lt;p&gt;What we will do is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a stack that contains nothing but the API Gateway&lt;/li&gt;
&lt;li&gt;Refer to this same API Gateway in all of our other stacks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This means that they will all be on the same URL, and we've only had to define it once.&lt;/p&gt;

&lt;p&gt;Our API Gateway stack will look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;service: serverless-gateway

provider:
  name: aws
  stage: dev

resources:
  Resources:
    ServerlessGW:
      Type: AWS::ApiGateway::RestApi
      Properties:
        Name: ServerlessGW-${opt:stage, self:provider.stage}
  Outputs:
    apiGatewayRestApiId:
      Value:
        Ref: ServerlessGW
      Export:
        Name: ServerlessGW-restApiId-${opt:stage, self:provider.stage}
    apiGatewayRestApiRootResourceId:
      Value:
        Fn::GetAtt:
          - ServerlessGW
          - RootResourceId
      Export:
        Name: ServerlessGW-rootResourceId-${opt:stage, self:provider.stage}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This creates an API Gateway with the name "ServerlessGW" and the name of the stage. The use of the stage means that we can deploy multiple stages at the same time - very useful when we come to do testing!&lt;/p&gt;

&lt;p&gt;We then refer to this in our other files as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;service: serverless-users

provider:
  name: aws
  apiGateway:
    restApiId:
      "Fn::ImportValue": ServerlessGW-restApiId-${opt:stage, self:provider.stage}
    restApiRootResourceId:
      "Fn::ImportValue": ServerlessGW-rootResourceId-${opt:stage, self:provider.stage}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;provider.apiGateway&lt;/code&gt; key tells Serverless that this stack will use that gateway, instead of defining it's own. Instantly we've got what we wanted.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementing a modular structure
&lt;/h2&gt;

&lt;p&gt;Unfortunately, the tooling doesn't easily support nested stacks. AWS CloudFormation and AWS SAM do, but to do so every single nested stack needs to be in S3 - both the CloudFormation scripts and the archive of contents. Only when all of these sub-stacks are in S3 can you then deploy the parent one. Serverless doesn't have any way to support this at present. It does have some plugins that get some of the way there, but none of them do the exact job that I want.&lt;/p&gt;

&lt;p&gt;As such, I've settled on a more DIY approach. It's possible to have stacks that are &lt;em&gt;not&lt;/em&gt; nested but still relate to each other, so we can simply have all the various parts of the application as different stacks with no direct connections between them except in terms of names. It's not perfect, but it works.&lt;/p&gt;

&lt;p&gt;This puts us into the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.
├── stacks
│   ├── gateway
│   │   ├── serverless.yml
│   └── users
│       ├── serverless.yml
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Every directory inside &lt;code&gt;stacks&lt;/code&gt; is then a single stack to be deployed.&lt;/p&gt;

&lt;p&gt;The next problem is that we need to do this in the correct order.&lt;/p&gt;

&lt;p&gt;My first thought was to do it a Node.js way. What we've actually got here is many projects that we want to orchestrate together. That should be easy, right? Wrong.&lt;/p&gt;

&lt;p&gt;The obvious thing to do is stick within the tooling stack. I'm using Node, so lets use Node tools.&lt;/p&gt;

&lt;h3&gt;
  
  
  Lerna
&lt;/h3&gt;

&lt;p&gt;There's a tool called Lerna that is explicitly designed for monorepos, and running tasks in multiple sub-modules correctly. So let use this.&lt;/p&gt;

&lt;p&gt;In order to do this, you need to have a package.json in each module, and one at the top level. The top-level one will depend on lerna and serverless, and have a few scripts entries to help run things. Our per-module ones will then have scripts entries for the actual work.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// ./package.json
{
  "name": "serverless",
  "scripts": {
    "sls:deploy": "lerna run sls:deploy",
    "sls:remove": "lerna run sls:remove"
  },
  "devDependencies": {
    "lerna": "^3.17.0",
    "serverless": "^1.54.0"
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// ./stacks/gateway/package.json
{
  "name": "serverless-gateway",
  "scripts": {
      "sls:package": "sls package",
      "sls:deploy": "sls deploy",
      "sls:remove": "sls remove"
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We then need a &lt;code&gt;lerna.json&lt;/code&gt; file to orchestrate this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "npmClient": "yarn",
  "packages": [ "stacks/gateway", "stacks/users" ],
  "version": "independent"
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We can now run &lt;code&gt;yarn sls:deploy&lt;/code&gt; at the top level and it will execute it in the sub-stacks, in the correct order, and deploy everything.&lt;/p&gt;

&lt;p&gt;Success? Not quite. This works fantastically for setting things up, but completely fails when tearing them down. If we execute &lt;code&gt;yarn sls:remove&lt;/code&gt; then it will try to remove &lt;code&gt;gateway&lt;/code&gt; &lt;em&gt;before&lt;/em&gt; &lt;code&gt;users&lt;/code&gt;, and that will fail. And there is no way at present to get Lerna to run in reverse direction. (There is an open issue for it though, so you never know!)&lt;/p&gt;

&lt;h3&gt;
  
  
  Gulp
&lt;/h3&gt;

&lt;p&gt;Next attempt. Gulp. There is a gulp plugin explicitly for serverless, and it will let you run serverless commands in directories. That's perfect.&lt;/p&gt;

&lt;p&gt;So we can set up our top-level package.json file as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "name": "serverless",
  "scripts": {
    "sls:deploy": "gulp deploy",
    "sls:remove": "gulp remove"
  },
  "devDependencies": {
    "gulp": "^4.0.2",
    "serverless": "^1.54.0",
    "serverless-gulp": "^1.0.10"
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Then we have a gulpfile.js file to orchestrate this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const gulp = require("gulp");
const serverlessGulp = require("serverless-gulp");

const paths = {
  serverless: ["gateway", "users"].map(p =&amp;gt; `stacks/${p}/serverless.yml`)
};

gulp.task("deploy", () =&amp;gt; {
  return gulp
    .src(paths.serverless, { read: false })
    .pipe(serverlessGulp.exec("deploy", { stage: "dev" }));
});

gulp.task("remove", () =&amp;gt; {
  return gulp
    .src(paths.serverless.reverse(), { read: false })
    .pipe(serverlessGulp.exec("remove", { stage: "dev" }));
});
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;With the above, when we run &lt;code&gt;yarn sls:deploy&lt;/code&gt; then we set everything up in the correct direction, but &lt;code&gt;yarn sls:remove&lt;/code&gt; now tears everything down in the opposite direction. Perfect.&lt;/p&gt;

&lt;p&gt;Only there's no easy way for Gulp to handle other monorepo tasks, like running tests across all the modules&lt;/p&gt;

&lt;h3&gt;
  
  
  Combined
&lt;/h3&gt;

&lt;p&gt;So we can achieve this by combining both tools. Gulp for the serverless tasks that need to have a strict order, and Lerna for the tasks that can happen in any order. Lerna can use wildcards for finding the modules, so we only need to maintain our ordered list in the Gulp configuration and all is good.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Building a Serverless application in a monorepo is not easy, but it is doable. And if you're a small team or an individual then it's worth the effort up front to make the rest of the process smoother.&lt;/p&gt;

</description>
      <category>serverless</category>
      <category>monorepo</category>
      <category>aws</category>
    </item>
    <item>
      <title>Building a larger Serverless application - Part 2: Tooling and Languages</title>
      <dc:creator>Graham Cox</dc:creator>
      <pubDate>Wed, 16 Oct 2019 06:26:37 +0000</pubDate>
      <link>https://dev.to/grahamcox82/building-a-larger-serverless-application-part-2-tooling-and-languages-2a1k</link>
      <guid>https://dev.to/grahamcox82/building-a-larger-serverless-application-part-2-tooling-and-languages-2a1k</guid>
      <description>&lt;p&gt;So, the obvious first thing that needs to be decided is &lt;em&gt;how&lt;/em&gt; to actually write an application. This means the language that we are working in and the tooling around it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tooling
&lt;/h2&gt;

&lt;p&gt;I'm aiming for AWS, simply because it's the big name and it's insanely comprehensive in what it offers whilst still being very affordable with the &lt;a href="https://aws.amazon.com/free/"&gt;Free Tier&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This means that we need to work out how to get software from my codebase up onto AWS. And there are several options for this.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Manually. Do not do this. This is &lt;em&gt;not&lt;/em&gt; sustainable in the long run, but it is technically an option. The AWS Web Console is insanely flexible and you can create all of the infrastructure resources you need from this.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Using the &lt;a href="https://aws.amazon.com/cli/"&gt;AWS CLI&lt;/a&gt;. This is technically possible, but it will take a lot of effort to keep things in sync correctly. And it is exactly this effort that the rest of the tools are designed to do for you.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://aws.amazon.com/cloudformation/"&gt;CloudFormation&lt;/a&gt;. This is the defacto AWS tool for managing infrastructure. We can write scripts that we store in our repo alongside our code, and use it to deploy the code. It works, but has a &lt;em&gt;lot&lt;/em&gt; of knowledge needed to actually achieve anything.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.terraform.io"&gt;Terraform&lt;/a&gt;. This is an alternative to CloudFormation that is agnostic of the provider we are deploying to.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://aws.amazon.com/serverless/sam/"&gt;AWS SAM&lt;/a&gt;. Where CloudFormation is designed for any AWS Infrastructure, SAM is a layer on top of it that is specifically targetted to the Serverless programming model. That makes it easier to work with for our use case, but it still gets quite in-depth very quickly.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://serverless.com"&gt;Serverless&lt;/a&gt;. This is another third-party, provider agnostic tool - like Terraform - but targetted at Serverless programming instead of Infrastructure in general.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The serverless tool is, from my experience, the best balance between flexibility and ease-of-use. It does a lot for you, but still allows you to do everything you want/need. You can literally put CloudFormation definitions in your scripts which means you can define anything you want, but if you use the Serverless structures it'll do a lot of heavy lifting for you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Language
&lt;/h2&gt;

&lt;p&gt;Once we know how to get our code up onto AWS, we need to decide what that code should be. Part of this is shaped by the platform itself, part by the tooling and part by our own preferences.&lt;/p&gt;

&lt;p&gt;If we're working in Serverless terms, i.e. we're writing Lambdas and having infrastructure connect them, then this immediately points us in certain directions.&lt;/p&gt;

&lt;p&gt;From my personal experience, the options that we get to are either Go or Node. These are the langauges that fit the Lambda process well - because they have library support for working with AWS and they have fast startup times.&lt;/p&gt;

&lt;p&gt;Out of those, I've then chosen to go with Node because it is slightly easier with the tooling - there's no need to pre-build it, and the resulting lambdas are smaller so they incur less S3 charges and take less time to deploy. This is nothing against Go - if you want to use it then it's still a fantastic fit. It just wasn't for me.&lt;/p&gt;

&lt;p&gt;On top of that, I'm actually going to use TypeScript instead of pure JavaScript. This is simply so that I get more modern features and to have typesafe code, but the actual tooling to get that into AWS is still quite small.&lt;/p&gt;

&lt;h3&gt;
  
  
  Getting TypeScript onto AWS
&lt;/h3&gt;

&lt;p&gt;To get TypeScript onto AWS we simply need to add some modules to our project and a specific serverless plugin. We need to install the &lt;a href="https://github.com/prisma-labs/serverless-plugin-typescript"&gt;serverless-plugin-typescript&lt;/a&gt; plugin, and all of the tooling needed for TypeScript itself to work.&lt;/p&gt;

&lt;p&gt;Importantly, make sure that all of this is set up as &lt;code&gt;devDependencies&lt;/code&gt;. That ensures that they are not in the resulting archive that gets uploaded - and they don't need to be - but they will still be used for the build process. This can make a &lt;em&gt;huge&lt;/em&gt; difference to the end result. Simply adding &lt;code&gt;typescript&lt;/code&gt; to the &lt;code&gt;dependencies&lt;/code&gt; section instead of the &lt;code&gt;devDependencies&lt;/code&gt; will inflate the archive by a whopping 10MB.&lt;/p&gt;

</description>
      <category>serverless</category>
      <category>aws</category>
      <category>node</category>
    </item>
    <item>
      <title>Building a larger Serverless application - Part 1: Getting started</title>
      <dc:creator>Graham Cox</dc:creator>
      <pubDate>Sat, 12 Oct 2019 12:53:00 +0000</pubDate>
      <link>https://dev.to/grahamcox82/building-a-larger-serverless-application-part-1-getting-started-553g</link>
      <guid>https://dev.to/grahamcox82/building-a-larger-serverless-application-part-1-getting-started-553g</guid>
      <description>&lt;p&gt;Serverless is often touted as a panacea for software delivery. It will let you write code must faster, deliver to production faster, be cheaper to run, make the tea, fix world hunger, etc. It's not, of course, but it can still be a good way to go in certain circumstances.&lt;/p&gt;

&lt;p&gt;So many tutorials and examples are written from the point of view of a single endpoint, or at best a couple. And as an API only service, with no client using it. That's great for absolute starters, but real life applications very quickly outgrow it.&lt;/p&gt;

&lt;p&gt;I'm going to attempt a series of articles that cover how to write a larger Serverless application, with a reasonable architecture to the backend, services that depend on each other, databases/queues/etc, a web frontend that can talk to it, and so on. There will also be an eye on how the actual code can be structured.&lt;/p&gt;

&lt;p&gt;These will be more aimed at solo or indie developers, rather than larger companies. As such, there will be more emphasis on free tooling and keeping complexity down - for example I'll probably aim for a monorepo because that's easier for a small set of people to handle.&lt;/p&gt;

&lt;p&gt;I can't guarantee it'll work. I can't promise that this will be any better than anything else out there. But we'll see how it goes.&lt;/p&gt;

</description>
      <category>serverless</category>
      <category>aws</category>
    </item>
    <item>
      <title>How to test views?</title>
      <dc:creator>Graham Cox</dc:creator>
      <pubDate>Sun, 06 Oct 2019 13:10:42 +0000</pubDate>
      <link>https://dev.to/grahamcox82/how-to-test-views-5592</link>
      <guid>https://dev.to/grahamcox82/how-to-test-views-5592</guid>
      <description>&lt;p&gt;Unusually for me, my current project I'm doing in the traditional Web 1.0 style. It's a forms based app, and the server is rendering HTML direct to the browser. And it's really efficient to work this way.&lt;/p&gt;

&lt;p&gt;Until you get to automated testing. With REST APIs, or GraphQL, or anything like that, you've got very obvious test points. For example, you have an API to get a user profile, and it just returns the exact JSON for the user. That's easy to test.&lt;/p&gt;

&lt;p&gt;With forms and views, you have a controller to render the user profile page, and this will render the entire screen of which a part is the user details. But there's a lot of other things going on too - page headers, menus, etc.&lt;/p&gt;

&lt;p&gt;Right now I'm doing snapshot testing. This is in Java, so I'm using jsoup to normalize the HTML - that ensures that irrelevant changes to the HTML, such as whitespace, don't affect the tests - and then asserting that the full rendered string is exactly correct.&lt;/p&gt;

&lt;p&gt;It works, but I don't like it. It feels clunky, and - well - wrong. It also doesn't ensure that it renders correctly, just that the string is as expected. If the CSS changes then this will make the page look wrong but the tests won't catch it! But I'm not sure yet what to do instead. &lt;/p&gt;

&lt;p&gt;So - what do other people do for this kind of testing? Is there a better way to do this?&lt;/p&gt;

</description>
      <category>testing</category>
      <category>tdd</category>
      <category>html</category>
      <category>question</category>
    </item>
    <item>
      <title>React without Redux, or How I learnt to embrace RxJS</title>
      <dc:creator>Graham Cox</dc:creator>
      <pubDate>Wed, 19 Jun 2019 17:30:50 +0000</pubDate>
      <link>https://dev.to/grahamcox82/react-without-redux-or-how-i-learnt-to-embrace-rxjs-1n05</link>
      <guid>https://dev.to/grahamcox82/react-without-redux-or-how-i-learnt-to-embrace-rxjs-1n05</guid>
      <description>&lt;p&gt;Whenever I start a new Webapp, I pretty much have the exact same set of libraries that I go to. React and Redux are high on that list. &lt;/p&gt;

&lt;p&gt;However, a lot of the time I find that the Redux store is being used for things that are very specific to one particular area of the UI, and &lt;em&gt;not&lt;/em&gt; for more global state. As such, recently I decided to try a different approach. Namely, the Context API and RxJS.&lt;/p&gt;

&lt;p&gt;Now, I've barely even started, but it already feels like it has potential.&lt;/p&gt;

&lt;p&gt;My first task here was authentication. It's an app that you &lt;em&gt;must&lt;/em&gt; be logged in to be able to do anything, so this was quite important. And to help streamline things, I've gone for the approach of separating the Email Address entry from the Login / Register forms, so that the system can detect if you're already registered or not and show the correct form.&lt;/p&gt;

&lt;p&gt;What this means is that I've got the following React component hierarchy:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;App

&lt;ul&gt;
&lt;li&gt;HomePage&lt;/li&gt;
&lt;li&gt;LoginRegister

&lt;ul&gt;
&lt;li&gt;EmailEntry&lt;/li&gt;
&lt;li&gt;Login&lt;/li&gt;
&lt;li&gt;Register&lt;/li&gt;
&lt;/ul&gt;


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

&lt;p&gt;The &lt;code&gt;EmailEntry&lt;/code&gt; component displays a simple form that asks for an Email Address. When the user submits one, it triggers an action to look up the email in the server, and then causes the &lt;code&gt;LoginRegister&lt;/code&gt; component to render either the &lt;code&gt;Login&lt;/code&gt; or &lt;code&gt;Register&lt;/code&gt; components as appropriate. In short, the state transitions are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;undefined =&amp;gt; EmailEntry&lt;/li&gt;
&lt;li&gt;PENDING =&amp;gt; EmailEntry, but with the loading indication to show that it's working&lt;/li&gt;
&lt;li&gt;EXISTS =&amp;gt; Login&lt;/li&gt;
&lt;li&gt;UNKNOWN =&amp;gt; Register&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, this all went into Redux and it all worked. The &lt;code&gt;EmailEntry&lt;/code&gt; component dispatched the &lt;code&gt;checkEmailAddress&lt;/code&gt; action. This caused Redux Saga to trigger, which:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dispatches the &lt;code&gt;checkEmailAddress_STARTED&lt;/code&gt; action&lt;/li&gt;
&lt;li&gt;Makes the API call&lt;/li&gt;
&lt;li&gt;Dispatches the &lt;code&gt;checkEmailAddress_SUCCESS&lt;/code&gt; action with the payload of &lt;code&gt;true&lt;/code&gt; or &lt;code&gt;false&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Dispatches the &lt;code&gt;checkEmailAddress_FINISHED&lt;/code&gt; action&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Reducers are then set up for the &lt;code&gt;checkEmailAddress_STARTED&lt;/code&gt; and &lt;code&gt;checkEmailAddress_SUCCESS&lt;/code&gt; actions to update the store values for &lt;code&gt;emailValue&lt;/code&gt; and &lt;code&gt;emailStatus&lt;/code&gt; as appropriate. &lt;/p&gt;

&lt;p&gt;The &lt;code&gt;LoginRegister&lt;/code&gt; component is then set to react to the &lt;code&gt;emailStatus&lt;/code&gt; value and render as appropriate.&lt;/p&gt;

&lt;p&gt;This is all very simple Redux. But it's also a lot of code. And almost all of this is very specific to this specific hierarchy of components. Nothing else in the application cares about the fact that we're checking an email address, what the email address is or what the status of the check is. And yet, it's in the global store for everything to see.&lt;/p&gt;

&lt;p&gt;So, I re-wrote it. I ripped Redux out entirely and instead wrote the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A simple module called &lt;code&gt;checkEmailService&lt;/code&gt; that has a single method - &lt;code&gt;checkEmail&lt;/code&gt;. This takes the email address and returns an &lt;code&gt;Observable&lt;/code&gt; for the result.&lt;/li&gt;
&lt;li&gt;When the form on the &lt;code&gt;EmailEntry&lt;/code&gt; form is submitted we then:

&lt;ul&gt;
&lt;li&gt;Update local state to show that the form is pending&lt;/li&gt;
&lt;li&gt;Call the &lt;code&gt;checkEmail&lt;/code&gt; method with the entered address&lt;/li&gt;
&lt;li&gt;Subscribe to the returned &lt;code&gt;Observable&lt;/code&gt;. When it resolves we call a callback provided from &lt;code&gt;LoginRegister&lt;/code&gt; with the email address and the result of the API call&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;When the &lt;code&gt;LoginRegister&lt;/code&gt; callback is triggered we update local state with the provided email address and status of it&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;LoginRegister&lt;/code&gt; component then uses this local state to determine which component to render.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This means that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The pending flag is local only to the &lt;code&gt;EmailEntry&lt;/code&gt; component&lt;/li&gt;
&lt;li&gt;The email address and status are local only to the &lt;code&gt;LoginRegister&lt;/code&gt; component&lt;/li&gt;
&lt;li&gt;There is &lt;em&gt;no&lt;/em&gt; global state at all&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That already feels cleaner. We've got rid of any global state, which is a huge plus (We all know how bad global variables are. Why is global state any better?)&lt;/p&gt;

&lt;p&gt;Sometimes though we do have values that are important to more of the application. For example, the Current User might be important, or the Authenticated Access Token. I've not yet implemented these, but I have two approaches for them in mind.&lt;/p&gt;

&lt;p&gt;For the actual global values, I'm going to use a &lt;code&gt;Subject&lt;/code&gt; - specifically a &lt;code&gt;BehaviorSubject&lt;/code&gt; - instead of an &lt;code&gt;Observable&lt;/code&gt;. The service calls can then update this as and when needed, and anything can subscribe to the current value. Access Token is one such value - it starts &lt;code&gt;undefined&lt;/code&gt;, but on authenticating it will be given a value. Anything that needs the current value will then be able to get it from the &lt;code&gt;Subject&lt;/code&gt; using &lt;code&gt;getValue&lt;/code&gt;, or can subscribe to get notified whenever it changes.&lt;/p&gt;

&lt;p&gt;For UI-centric concerns, I'm considering coupling this with the Context API and have a component in the appropriate part of the component tree act as the Provider and subscribe to the &lt;code&gt;Subject&lt;/code&gt;. Whenever the &lt;code&gt;Subject&lt;/code&gt; changes, this component updates it's local value and passes it into the Context API. Anything lower down that needs it can then access it from the Context API without needing to know about the API calls that generated it. This means that there's only a single subscriber to the &lt;code&gt;Subject&lt;/code&gt; that needs to do the updates, and React handles the rest.&lt;/p&gt;

&lt;p&gt;All of this seems to give me the majority of Redux functionality without any need for Redux itself.&lt;/p&gt;

&lt;p&gt;The bit that's missing is orchestration. The fact that a single dispatched action can cause multiple bits of the store to react. This is also relatively simple to achieve by simply having service APIs that call other service APIs. For example, the act of authentication is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Send the Email and Password to the Server, and get back an Access Token and User ID&lt;/li&gt;
&lt;li&gt;Store the Access Token&lt;/li&gt;
&lt;li&gt;Store the User ID as the Current User ID&lt;/li&gt;
&lt;li&gt;Call the server to get the User Details for the Current User ID&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Redux allows a lot of this to happen by different parts of the store reacting to the same actions. For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;authenticate_SUCCESS&lt;/code&gt; causes the Access Token Reducer to store the Access Token&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;authenticate_SUCCESS&lt;/code&gt; causes the Current User Reducer to store the User ID&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;authenticate_SUCCESS&lt;/code&gt; causes a Saga to dispatch the &lt;code&gt;getUser&lt;/code&gt; action with the given User ID&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;getUser_SUCCESS&lt;/code&gt; causes the User Details Reducer to store the user details&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All chained off of a single action. That works, but it's difficult to trace through it in the code. Instead, I'm planning on having an &lt;code&gt;authenticationService&lt;/code&gt; which:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Calls the &lt;code&gt;accessTokenService&lt;/code&gt; to get the Access Token&lt;/li&gt;
&lt;li&gt;Calls the &lt;code&gt;currentUserService&lt;/code&gt; to store the User ID&lt;/li&gt;
&lt;li&gt;Calls the &lt;code&gt;getUserService&lt;/code&gt; to get (and cache) the User Details&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This gives very readable orchestration, and makes debugging and testing it very simple.&lt;/p&gt;

&lt;p&gt;Will it work? I don't know yet.&lt;/p&gt;

&lt;p&gt;Will it be better than Redux? I don't know yet.&lt;/p&gt;

&lt;p&gt;But I fully intend to see how it goes.&lt;/p&gt;

</description>
      <category>react</category>
      <category>redux</category>
      <category>rxjs</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Kotlin classes implementing Functions</title>
      <dc:creator>Graham Cox</dc:creator>
      <pubDate>Wed, 02 Jan 2019 21:54:14 +0000</pubDate>
      <link>https://dev.to/grahamcox82/kotlin-classes-implementing-functions-18e8</link>
      <guid>https://dev.to/grahamcox82/kotlin-classes-implementing-functions-18e8</guid>
      <description>&lt;p&gt;Little trick that I discovered today. &lt;/p&gt;

&lt;p&gt;As you probably know, in Kotlin - as in Java 8 - a Function is able to implement a Single Method Interface, as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;        Assertions.assertAll(
                Executable { Assertions.assertEquals(clientId, token.client) },
                Executable { Assertions.assertEquals(userId, token.user) },
                Executable { Assertions.assertEquals(NOW, token.issued) },
                Executable { Assertions.assertEquals(NOW.plus(duration), token.expires) },
                Executable { Assertions.assertEquals(setOf(GlobalScopes.ALL), token.scopes) }
        )
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Each of those &lt;code&gt;Executable&lt;/code&gt; entries is defining a function that matches the &lt;code&gt;Executable&lt;/code&gt; interface.&lt;/p&gt;

&lt;p&gt;However, the opposite is also true. You can write a class that can be used anywhere a particular function type is expected. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class UUIDNonceGenerator : () -&amp;gt; String {
    /**
     * Generate the Nonce
     * @return the nonce
     */
    override operator fun invoke() = UUID.randomUUID().toString()
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;An instance of this class is usable anywhere that a function that takes 0 parameters and returns a string - a &lt;code&gt;() -&amp;gt; String&lt;/code&gt; - is accepted.&lt;/p&gt;

&lt;p&gt;The reasoning for this is actually quite sound. The class actually implements &lt;code&gt;kotlin.jvm.functions.Function0&amp;lt;java.lang.String&amp;gt;&lt;/code&gt;, which is exactly what &lt;code&gt;() -&amp;gt; String&lt;/code&gt; means. So it's actually just a class implementing an interface. It just so happens that this works both ways, so anything that also accepts a &lt;code&gt;() -&amp;gt; String&lt;/code&gt; actually accepts a &lt;code&gt;kotlin.jvm.functions.Function0&amp;lt;java.lang.String&amp;gt;&lt;/code&gt;, and thus the types match. Voila.&lt;/p&gt;

&lt;p&gt;Not sure how useful this is, but it's there if you need it.&lt;/p&gt;

</description>
      <category>kotlin</category>
    </item>
    <item>
      <title>Running all JUnit Tests on the Classpath</title>
      <dc:creator>Graham Cox</dc:creator>
      <pubDate>Tue, 25 Sep 2018 12:55:42 +0000</pubDate>
      <link>https://dev.to/grahamcox82/running-all-junit-tests-on-the-classpath-3hpf</link>
      <guid>https://dev.to/grahamcox82/running-all-junit-tests-on-the-classpath-3hpf</guid>
      <description>&lt;p&gt;I've been tinkering with this for a while, and have finally found a reliable way to run all of the JUnit tests that exist on the classpath. In my case this is so that I can package up my end-to-end tests as an executable JAR and run them in a Docker container, but there are various other use cases as well.&lt;/p&gt;

&lt;p&gt;This code is in Groovy, because I'm doing this with Spock and Geb, but it'll work just as well in any JVM language.&lt;/p&gt;

&lt;p&gt;Note as well that this uses the fantastic &lt;a href="https://github.com/classgraph/classgraph"&gt;ClassGraph API&lt;/a&gt; for finding the tests.&lt;/p&gt;

&lt;p&gt;So - here's the code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import io.github.classgraph.ClassGraph
import org.junit.internal.TextListener
import org.junit.runner.JUnitCore
import org.junit.runner.Request

class RunAllTests {
    static void main(String... args) {

        def testClasses = new ClassGraph()
                .whitelistPackages(RunAllTests.class.packageName)
                .scan()
                .allClasses
                .filter { it.name.endsWith("Spec") }
                .loadClasses()


        def runner = new JUnitCore()
        runner.addListener(new TextListener(System.err))

        def testRequest = Request.classes(*testClasses.toArray())

        def result = runner.run(testRequest)
        System.exit(result.wasSuccessful() ? 0 : 1)
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's as simple as that. That finds everything that is in the same package as the &lt;code&gt;RunAllTests&lt;/code&gt; class or below, and that has a class name ending in &lt;code&gt;Spec&lt;/code&gt;, and then runs them all.&lt;/p&gt;

</description>
      <category>groovy</category>
      <category>junit</category>
      <category>testing</category>
    </item>
    <item>
      <title>What makes a good software design document?</title>
      <dc:creator>Graham Cox</dc:creator>
      <pubDate>Mon, 17 Sep 2018 15:04:57 +0000</pubDate>
      <link>https://dev.to/grahamcox82/what-makes-a-good-software-design-57o9</link>
      <guid>https://dev.to/grahamcox82/what-makes-a-good-software-design-57o9</guid>
      <description>&lt;p&gt;In my role at work, I do a lot of design work. Not graphical design - or our product would look awful! - but technical design. The documents that describe how to get from where we are now - with feature ABC missing, to where we want to be - with feature ABC present.&lt;/p&gt;

&lt;p&gt;I'd like to think I'm quite good at this. But I know for a fact that I could be a lot better. We all could.&lt;/p&gt;

&lt;p&gt;So, I ask you, when you produce, or read, these kinds of designs, what makes it good and what makes it bad? How can I do better at this?&lt;/p&gt;

&lt;p&gt;(My own thoughts will follow in the comments later on, to avoid leading any discussions...)&lt;/p&gt;

</description>
      <category>discuss</category>
    </item>
    <item>
      <title>OAuth 2.0 and OpenID Connect Flows</title>
      <dc:creator>Graham Cox</dc:creator>
      <pubDate>Mon, 04 Jun 2018 12:06:52 +0000</pubDate>
      <link>https://dev.to/grahamcox82/oauth-20-and-openid-connect-flows-283j</link>
      <guid>https://dev.to/grahamcox82/oauth-20-and-openid-connect-flows-283j</guid>
      <description>&lt;p&gt;This post is partly for my own benefit, and partly for people to tell me that I've completely misunderstood things. So please, if it's wrong then tell me!&lt;/p&gt;

&lt;p&gt;OAuth 2.0 offers two standard flows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Authorization Code Grant - &lt;code&gt;response_type=code&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;OAuth 2.0 Implicit Grant - &lt;code&gt;response_type=token&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;OpenID Connect then augments these with the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;OIDC Implicit Grant - &lt;code&gt;response_type=id_token token&lt;/code&gt; or &lt;code&gt;response_type=id_token&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Hybrid Flow - &lt;code&gt;response_type=code id_token&lt;/code&gt;, &lt;code&gt;response_type=code token&lt;/code&gt; or &lt;code&gt;response_type=code id_token token&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In actuality, these all work in the exact same way:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If &lt;code&gt;response_type&lt;/code&gt; contains &lt;code&gt;code&lt;/code&gt; then generate and return an Authorization Code that can be exchanged for an Access Token

&lt;ul&gt;
&lt;li&gt;In this case, if &lt;code&gt;scope&lt;/code&gt; contains &lt;code&gt;openid&lt;/code&gt; then include an ID Token as well as an Access Token in the response from the Token endpoint.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;If &lt;code&gt;response_type&lt;/code&gt; contains &lt;code&gt;token&lt;/code&gt; then generate and return an Access Token - though probably a more tightly restricted one that expires sooner.

&lt;ul&gt;
&lt;li&gt;In this case, return the parameters as a Fragment on the redirect. If this is not present then return the parameters as a Querystring instead.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;If &lt;code&gt;response_type&lt;/code&gt; contains &lt;code&gt;id_token&lt;/code&gt; then generate and return an ID Token.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These three rules can then be mixed and matched however is wished to give the combinations that are covered in the spec. &lt;/p&gt;

&lt;p&gt;However, interestingly enough, if you follow these three rules instead then you get more flexibility. For example, the specs allow for all 7 combinations but only in a specific ordering - which happens to be alphabetical. Ignoring that fact would allow you to also accept:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;code token id_token&lt;/li&gt;
&lt;li&gt;token code&lt;/li&gt;
&lt;li&gt;id_token code token&lt;/li&gt;
&lt;li&gt;etc&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I don't see that there's a whole lot of benefit to this, but the flexibility that you gain by making the rules &lt;em&gt;simpler&lt;/em&gt; seems to be of some use.&lt;/p&gt;

&lt;p&gt;Additionally, the rules for mandatory inputs are apparently that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;scope - always REQUIRED&lt;/li&gt;
&lt;li&gt;response_type - always REQUIRED&lt;/li&gt;
&lt;li&gt;client_id - always REQUIRED&lt;/li&gt;
&lt;li&gt;redirect_uri - always REQUIRED&lt;/li&gt;
&lt;li&gt;state - always RECOMMENDED&lt;/li&gt;
&lt;li&gt;nonce - REQUIRED if response_type contains &lt;code&gt;id_token&lt;/code&gt; but not &lt;code&gt;code&lt;/code&gt;. OPTIONAL otherwise.

&lt;ul&gt;
&lt;li&gt;I don't get this one, but the OpenID Connect specification explicitly marks &lt;code&gt;nonce&lt;/code&gt; as REQUIRED only during the OIDC Implicit Flow, and not in the others.&lt;/li&gt;
&lt;/ul&gt;


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

&lt;p&gt;Am I missing anything here? Or is it really that this simpler interpretation gives everything needed from the spec?&lt;/p&gt;

</description>
      <category>oauth2</category>
      <category>openid</category>
      <category>discuss</category>
    </item>
    <item>
      <title>... Or how I learned to stop worrying and love the magic</title>
      <dc:creator>Graham Cox</dc:creator>
      <pubDate>Sat, 26 May 2018 09:25:30 +0000</pubDate>
      <link>https://dev.to/grahamcox82/-or-how-i-learned-to-stop-worrying-and-love-the-magic-2811</link>
      <guid>https://dev.to/grahamcox82/-or-how-i-learned-to-stop-worrying-and-love-the-magic-2811</guid>
      <description>&lt;p&gt;There was a time in my career when I'd want to do everything myself. I'd rationalise it away as learning how to do things, but I'd be much happier if I was doing things myself rather than depending on others to have already done it.&lt;/p&gt;

&lt;p&gt;This ranged from small things - 3d maths libraries, for example - up to huge things - I once wrote a fully compliant websockets server using only Java NIO!&lt;/p&gt;

&lt;p&gt;Over time I got less attached to this and more embraced existing libraries. After all, they were written by very clever people, and already did everything that I needed. For example, using the websockets support in Spring instead. This, obviously enough, made me significantly more productive - reinventing everything is a slow process, and a relatively pointless.&lt;/p&gt;

&lt;p&gt;However, I still shied away from "magic" if I didn't write it myself. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Side note: what is magic? It's anything where the exact outcome works but you can't immediately see &lt;em&gt;why&lt;/em&gt; or &lt;em&gt;how&lt;/em&gt; it works.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This meant I was happy to use Spring, but stayed away from Spring Boot - preferring to wire everything up by hand so I could see it all.&lt;/p&gt;

&lt;p&gt;And, over time, even this has changed. I recently wrote a mock server for work, using Spring Boot, Spring Starter, Spring Shell. Heck, I even used component scanning. (That still does make me feel dirty, but for what I feel are very good reasons - it's very difficult to scale up to medium or large systems and still know how it works...)&lt;/p&gt;

&lt;p&gt;And you know what? The magic isn't scary. It works. It does exactly what it's meant to, and it lets you do everything else.&lt;/p&gt;

&lt;p&gt;That mock server, from start to end, too about 3 hours. Old me would have spent a week on it! How's that for productive...&lt;/p&gt;

</description>
      <category>design</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
