AWS Amplify and Clojurescript Re-Frame Part 1

As the Chief Architect, Rob guides the evolution of the InformedIQ Software and Infrastructure. His experience spans the rise and fall of many technology lifecycles from machine vision, digitization of professional video production equipment, Internet Infrastructure, Wireless, E-commerce, Big Data, IoT, DevOps and Machine Learning. He has been a founder or a technical leader in several startups in Silicon Valley.
Previously: CoFounder / CTO / SVP of Engineering at Omnyway, Rob is leading the software development and infrastructure efforts of Omnyway Inc. His long history as an early adopter of DevOps, Lean culture and Cloud technology drives Omnyway’s continuous integration / continuous delivery workflow and operations.
Prior to Omnyway, Rob was the Cloud Architect at Mist Systems Inc (http://www.mist.com), where he designed, and led the implementation of the Cloud / Realtime big data Infrastructure and Continuous Delivery process. Mist’s mission is transforming the Indoor Location and WiFi Experience.
From 2008 to May 2013, Rob was a co-founder and the CTO of Runa Inc., developing and deploying a Big Data Cloud based Software as a Service for online merchants. Runa increases conversion of shoppers while on the merchant's site using real-time, individualized promotions. While at Runa he pushed the state-of-the-art in personalization, service scaling, statistical / semantic processing and ajax technologies. Our system architecture includes the use of AWS, HBase/Hadoop, Clojure, AMQP/RabbitMQ, Redis and Opscode Chef. Runa was sold to Staples in 2013.
As the President and Founder of Internet Bandwidth Development since 1998 and as a principal at Opscale from Apr 2013 - Sept 2014, Rob has delivered hands-on design and development to many SaaS, IaaS, PaaS and Big Data companies in Silicon Valley. He has helped them deploy their services, improve their monitoring and implement Continuous Delivery on a variety of Private and Public Cloud / Virtualization Environments. He has created several custom deployment, CI, monitoring and management tools.
Rob has been a principal or founder in several other start-up network services and equipment companies including InterNex, MetroFi and UltraDevices. As an Internet pioneer in the early 90’s, Rob founded InterNex Services which was the first ISP to offer commercial ISDN Internet services, Frame Relay and higher speed business broadband services as well as one of the first o offer shared, dedicated and International Hosting Services. InterNex was later acquired by Concentric/XO.
In 2002 - 2003 Rob was a visiting research fellow at the Center for Global Communications (GLOCOM www.glocom.ac.jp) in Tokyo with a focus on Open Spectrum technology (UltraWideband spread spectrum, Cognitive / Software Defined Radios, Wireless Mesh Networks, expanded unlicensed 802.11 wireless) and how it impacts spectrum policy.
Over the years Rob has provided technology consulting in Architecture, Due Diligence & Design Review/Evaluation in the realms of backbone networks, access networks, wireless networks, DevOps, software development and innovative Internet/Web applications and services to technology start-ups, top names in Internet hardware and software, as well as venture capital firms, including NEA, Athena Ventures and Panorama Capital.
Companies Rob has worked with as a consultant or advisor include Staples Labs, RFSpot, Continuuity, ElasticBox, Deutsche Telekom Hosted Business Services, Equilar, RiverMeadow, SkyPilot Networks, VISA, Cisco, Ascend, iPass, and Oki Networks. Through IBD he has provided services Rob has been on the Advisory Boards of companies including Netenrich, Vistara, TelTel, Covad, Alteon WebSystems (acquired by Nortel), AboveNet, WeFi, BooRah, GridNetworks, Cloudscaling, Support Intelligence, Cosine Communications and most recently Compass (http://compass.co).
He has been a speaker on Next Generation Networks and DevOps / Cloud Technologies at conferences including RedDotRuby Singapore, HBaseCon, CTIA and APRICOT (Asia Pacific Regional Internet Conference on Operational Technologies).
Introduction
AWS Amplify
AWS Amplify makes it super simple to build Web and Mobile Apps that use the entire suite of AWS Services with minimal coding by the app developer. Clojurescript and Re-Frame make creating SPA apps a joy. The combination of all three is truly a superpower!
The AWS Amplify CLI makes it easy to setup various AWS services and make them available via the Amplify SDK to your Web or Mobile App. It also has great support for React based apps.
The goal of this project is to show how to be able to use AWS Amplify with Clojurescript / Re-Frame Web Apps.
The initial AWS feature to incorporate is the Amplify Authentication service which has AWS Cognito at its core. Amplify offers a React Higher Order Component that allows you to wrap your JS app with Authentication.
- Ensures that your App can only be accessed when authenticated
Handles all the UI and API integration with Cognito
- You do not have to write any of the code
- Sign-up
- Verify phone_number or email address
- Sign-in
- Sign-out
- Forgot Password
- Password reset
Optionally (and not described in this first article but easy to add)
- Customize Authenticator UI
- Use your own UI components
- AWS Auth for AWS services which require signing requests.
- Social Provider Federation / OAuth
- Force new password
- Multi-Factor Authentication
- User Attributes
- Lambda Triggers
Note: This article and its followup AWS Amplify and Clojurescript Re-Frame Part 2: Deploy to Production Cloudfront are based on branch basic-amplify-with-cloudfront of the omnyway-labs/amplify_cljs_example repo.
Re-Frame / Clojurescript / Shadow-cljs
The main goal of this project is to show how to leverage Amplify in a Clojurescript Single Page App (SPA). In particular, using the re-frame Clojurescript Library.
Re-frame is a functional framework for building SPAs leveraging Reagent. Reagent is a minimalistic interface between ClojureScript and React.
Clojurescript is hosted on Javascript and can naturally interoperate with Javascript in general. This project uses shadow-cljs as the buildtool. Its major superpower is to make it pretty easy to leverage node.js packages. The main features it offers include:
- Good configuration defaults so you don't have to sweat the details
- Seamless npm integration
- Fast builds, reliable caching, ...
- Supporting various targets :browser, :node-script, :npm-module, :react-native, :chrome-extension, ...
- Live Reload (CLJS + CSS)
- CLJS REPL
- Code splitting (via :modules)
Put together, these tools allows one to build SPAs in a functional / Clojure centric way, but still leverage all the wonders of React and node.
That being said. There are a lot of learning curves that also need to be climbed to make it all work together.
This project is an attempt to make it easier for folks to jump right in. It can be used as a starting point to build your own SPA with sophisticated Authentication services.
This article and the associated github repo omnyway-labs/amplify_cljs_example should tell you everything you need from scratch to get you to a working basis of a re-frame SPA running on your local machine with full AWS Cognito Simple Authentication backend. The amount of code you have to write to make it work is surprisingly trivial due to the scaffolding features of re-frame and the AWS generation / auto-configuration of Amplify.
The second article in this series Deploy to CloudFront with Amplify Console shows how to deploy the SPA to AWS CloudFront with minimal effort.
Assumptions
You have already installed the following on your laptop / dev machine:
- An AWS Account that you have administrative access to
- git (Ideally have a github account)
- Java
- Node.js and npm
- Clojure
- Clojurscript
- shadow-cljs
- leiningen
- Have an editor and know how to use it
Initial Setup
We're using the re-frame scaffold template to create the initial app. We're not going to add much to the app in this article other than the Amplify Authentication wrapper.
Later articles will add more functionality so we're including some extras like garden for doing CSS in clojure. More importantly we're including re-com Which is a library of ClojureScript UI components, built on top of Reagent. It integrates with re-frame in a very functional / clojure way.
10x is a very nice debugging dashboard for re-frame. Again, won't be using it until later articles but its something you will want to have if you use this for building on top of.
- Generate the scaffold
lein new re-frame amplify_cljs_example +10x +cider +re-com +test +garden
cd amplify_cljs_example
lein garden once
git init
- Update .gitignore by adding:
/resources/public/css/screen.css
.shadow-cljs
node_modules
- More setup; build and run the local instance of the initial scaffolded SPA
git add -A
git commit -a -m "Initial commit after lein new re-frame amplify_cljs_example +10x +cider +re-com +test +garden"
npm install
git add package-lock.json
git commit -m "package-lock for npm" package-lock.json
lein garden once
lein dev
The lein dev will build and run the application locally. It doesn't exit, it keeps running, monitoring the app files. If there are any changes it will automatically hot load the application. Lein is effectively running shadow-cljs watch app
- The
lein devprobably added more packages for npm and so you should update your git in another shell window in the same directorygit commit -m "lein updates to package.json" package-lock.json package.jsonEnsure the basics are working
So if the lein dev is running properly, it will end with:
[:app] Build completed. (1659 files, 1658 compiled, 0 warnings, 46.89s)
At that point, you should be able to:
- Go to
http://localhost:8280in a browser (Chrome is optimal) - Should look something like:

Set up AWS Amplify
- You should be in the top level of the
amplify_cljs_exampledirectory Assuming you don’t already have AWS Amplify installed on your dev machine:
npm install -g @aws-amplify/cli amplify configureFollow the instructions as described in Installing & Configuring the AWS Amplify CLI - YouTube to configure you local dev amplify environment to manage your AWS environment
- Initialize the Amplify project.
- Mostly accept the defaults or as appropriate for you
- Start command :
lein dev - AWS Profile yes and use the one you created when you did
amplify configurewhich by default isdefault```amplify init Scanning for plugins... Plugin scan successful Note: It is recommended to run this command from the root of your app directory ? Enter a name for the project reframerecomamplifye ? Enter a name for the environment dev ? Choose your default editor: Emacs (via Terminal, Mac OS only) ? Choose the type of app that you're building javascript Please tell us about your project ? What javascript framework are you using react ? Source Directory Path: src ? Distribution Directory Path: build ? Build Command: lein prod ? Start Command: lein dev Using default provider awscloudformation
For more information on AWS Profiles, see: https://docs.aws.amazon.com/cli/latest/userguide/cli-multiple-profiles.html
? Do you want to use an AWS profile? Yes ? Please choose the profile you want to use default ⠧ Initializing project in the cloud...
CREATE_IN_PROGRESS AuthRole AWS::IAM::Role Fri Oct 04 2019 22:50:40 GMT-0700 (Pacific Daylight Time) Resource creation Initiated CREATE_IN_PROGRESS DeploymentBucket AWS::S3::Bucket Fri Oct 04 2019 22:50:40 GMT-0700 (Pacific Daylight Time) Resource creation Initiated CREATE_IN_PROGRESS UnauthRole AWS::IAM::Role Fri Oct 04 2019 22:50:40 GMT-0700 (Pacific Daylight Time) Resource creation Initiated CREATE_IN_PROGRESS AuthRole AWS::IAM::Role Fri Oct 04 2019 22:50:39 GMT-0700 (Pacific Daylight Time) CREATE_IN_PROGRESS DeploymentBucket AWS::S3::Bucket Fri Oct 04 2019 22:50:39 GMT-0700 (Pacific Daylight Time) CREATE_IN_PROGRESS UnauthRole AWS::IAM::Role Fri Oct 04 2019 22:50:39 GMT-0700 (Pacific Daylight Time) CREATE_IN_PROGRESS reframerecomamplifye-dev-20191004225035 AWS::CloudFormation::Stack Fri Oct 04 2019 22:50:36 GMT-0700 (Pacific Daylight Time) User Initiated ⠴ Initializing project in the cloud...
CREATE_COMPLETE UnauthRole AWS::IAM::Role Fri Oct 04 2019 22:50:52 GMT-0700 (Pacific Daylight Time) ⠏ Initializing project in the cloud...
CREATE_COMPLETE AuthRole AWS::IAM::Role Fri Oct 04 2019 22:50:52 GMT-0700 (Pacific Daylight Time) ⠹ Initializing project in the cloud...
CREATE_COMPLETE DeploymentBucket AWS::S3::Bucket Fri Oct 04 2019 22:51:01 GMT-0700 (Pacific Daylight Time) ⠇ Initializing project in the cloud...
CREATE_COMPLETE reframerecomamplifye-dev-20191004225035 AWS::CloudFormation::Stack Fri Oct 04 2019 22:51:03 GMT-0700 (Pacific Daylight Time) ✔ Successfully created initial AWS cloud resources for deployments. ✔ Initialized provider successfully. Initialized your environment successfully.
Your project has been successfully initialized and connected to the cloud!
* Add the Amplify Authentication service
* Details at [AWS Amplify Authentication](https://aws-amplify.github.io/docs/js/authentication)
* Sign-in: Selecting 'Email' and/or 'Phone Number' will allow end users to sign-up using these values. Selecting 'Username' will require a unique username for users.
amplify add auth Using service: Cognito, provided by: awscloudformation
The current configured provider is Amazon Cognito.
Do you want to use the default authentication and security configuration? Default configuration Warning: you will not be able to edit these selections. How do you want users to be able to sign in? Email Do you want to configure advanced settings? No, I am done. Successfully added resource reframerecomamplifye16cd456a locally
* Push the auth feature / config to AWS
amplify auth push
Current Environment: dev
| Category | Resource name | Operation | Provider plugin |
| Auth | reframerecomamplifye16cd456a | Create | awscloudformation |
? Are you sure you want to continue? Yes ⠹ Updating resources in the cloud. This may take a few minutes...
CREATE_IN_PROGRESS UpdateRolesWithIDPFunctionRole AWS::IAM::Role Fri Oct 04 2019 23:08:01 GMT-0700 (Pacific Daylight Time) Resource creation Initiated CREATE_IN_PROGRESS authreframerecomamplifye16cd456a AWS::CloudFormation::Stack Fri Oct 04 2019 23:08:01 GMT-0700 (Pacific Daylight Time) Resource creation Initiated CREATE_IN_PROGRESS authreframerecomamplifye16cd456a AWS::CloudFormation::Stack Fri Oct 04 2019 23:08:01 GMT-0700 (Pacific Daylight Time) CREATE_IN_PROGRESS UpdateRolesWithIDPFunctionRole AWS::IAM::Role Fri Oct 04 2019 23:08:00 GMT-0700 (Pacific Daylight Time) UPDATE_IN_PROGRESS reframerecomamplifye-dev-20191004225035 AWS::CloudFormation::Stack Fri Oct 04 2019 23:07:57 GMT-0700 (Pacific Daylight Time) User Initiated ⠇ Updating resources in the cloud. This may take a few minutes...
CREATE_IN_PROGRESS reframerecomamplifye-dev-20191004225035-authreframerecomamplifye16cd456a-19BSJYQRK36 AWS::CloudFormation::Stack Fri Oct 04 2019 23:08:01 GMT-0700 (Pacific Daylight Time) User Initiated ⠋ Updating resources in the cloud. This may take a few minutes...
CREATE_IN_PROGRESS SNSRole AWS::IAM::Role Fri Oct 04 2019 23:08:08 GMT-0700 (Pacific Daylight Time) Resource creation Initiated CREATE_IN_PROGRESS SNSRole AWS::IAM::Role Fri Oct 04 2019 23:08:07 GMT-0700 (Pacific Daylight Time) ⠴ Updating resources in the cloud. This may take a few minutes...
CREATE_COMPLETE UpdateRolesWithIDPFunctionRole AWS::IAM::Role Fri Oct 04 2019 23:08:15 GMT-0700 (Pacific Daylight Time) ⠋ Updating resources in the cloud. This may take a few minutes...
CREATE_COMPLETE SNSRole AWS::IAM::Role Fri Oct 04 2019 23:08:20 GMT-0700 (Pacific Daylight Time) ⠙ Updating resources in the cloud. This may take a few minutes...
CREATE_COMPLETE UserPool AWS::Cognito::UserPool Fri Oct 04 2019 23:08:27 GMT-0700 (Pacific Daylight Time) CREATE_IN_PROGRESS UserPool AWS::Cognito::UserPool Fri Oct 04 2019 23:08:27 GMT-0700 (Pacific Daylight Time) Resource creation Initiated CREATE_IN_PROGRESS UserPool AWS::Cognito::UserPool Fri Oct 04 2019 23:08:24 GMT-0700 (Pacific Daylight Time) ⠇ Updating resources in the cloud. This may take a few minutes...
CREATE_COMPLETE UserPoolClientWeb AWS::Cognito::UserPoolClient Fri Oct 04 2019 23:08:33 GMT-0700 (Pacific Daylight Time) CREATE_IN_PROGRESS UserPoolClientWeb AWS::Cognito::UserPoolClient Fri Oct 04 2019 23:08:33 GMT-0700 (Pacific Daylight Time) Resource creation Initiated CREATE_COMPLETE UserPoolClient AWS::Cognito::UserPoolClient Fri Oct 04 2019 23:08:33 GMT-0700 (Pacific Daylight Time) CREATE_IN_PROGRESS UserPoolClient AWS::Cognito::UserPoolClient Fri Oct 04 2019 23:08:32 GMT-0700 (Pacific Daylight Time) Resource creation Initiated CREATE_IN_PROGRESS UserPoolClientWeb AWS::Cognito::UserPoolClient Fri Oct 04 2019 23:08:31 GMT-0700 (Pacific Daylight Time) CREATE_IN_PROGRESS UserPoolClient AWS::Cognito::UserPoolClient Fri Oct 04 2019 23:08:31 GMT-0700 (Pacific Daylight Time) ⠙ Updating resources in the cloud. This may take a few minutes...
CREATE_IN_PROGRESS UserPoolClientRole AWS::IAM::Role Fri Oct 04 2019 23:08:36 GMT-0700 (Pacific Daylight Time) Resource creation Initiated CREATE_IN_PROGRESS UserPoolClientRole AWS::IAM::Role Fri Oct 04 2019 23:08:36 GMT-0700 (Pacific Daylight Time) ⠏ Updating resources in the cloud. This may take a few minutes...
CREATE_COMPLETE UserPoolClientRole AWS::IAM::Role Fri Oct 04 2019 23:08:48 GMT-0700 (Pacific Daylight Time) ⠹ Updating resources in the cloud. This may take a few minutes...
CREATE_COMPLETE UserPoolClientLambda AWS::Lambda::Function Fri Oct 04 2019 23:08:52 GMT-0700 (Pacific Daylight Time) CREATE_IN_PROGRESS UserPoolClientLambda AWS::Lambda::Function Fri Oct 04 2019 23:08:52 GMT-0700 (Pacific Daylight Time) Resource creation Initiated CREATE_IN_PROGRESS UserPoolClientLambda AWS::Lambda::Function Fri Oct 04 2019 23:08:52 GMT-0700 (Pacific Daylight Time) ⠸ Updating resources in the cloud. This may take a few minutes...
CREATE_IN_PROGRESS UserPoolClientLambdaPolicy AWS::IAM::Policy Fri Oct 04 2019 23:08:57 GMT-0700 (Pacific Daylight Time) Resource creation Initiated CREATE_IN_PROGRESS UserPoolClientLambdaPolicy AWS::IAM::Policy Fri Oct 04 2019 23:08:56 GMT-0700 (Pacific Daylight Time) ⠼ Updating resources in the cloud. This may take a few minutes...
CREATE_COMPLETE UserPoolClientLambdaPolicy AWS::IAM::Policy Fri Oct 04 2019 23:09:02 GMT-0700 (Pacific Daylight Time) ⠋ Updating resources in the cloud. This may take a few minutes...
CREATE_IN_PROGRESS UserPoolClientLogPolicy AWS::IAM::Policy Fri Oct 04 2019 23:09:06 GMT-0700 (Pacific Daylight Time) ⠸ Updating resources in the cloud. This may take a few minutes...
CREATE_IN_PROGRESS UserPoolClientLogPolicy AWS::IAM::Policy Fri Oct 04 2019 23:09:06 GMT-0700 (Pacific Daylight Time) Resource creation Initiated ⠸ Updating resources in the cloud. This may take a few minutes...
CREATE_COMPLETE UserPoolClientLogPolicy AWS::IAM::Policy Fri Oct 04 2019 23:09:12 GMT-0700 (Pacific Daylight Time) ⠸ Updating resources in the cloud. This may take a few minutes...
CREATE_IN_PROGRESS UserPoolClientInputs Custom::LambdaCallout Fri Oct 04 2019 23:09:15 GMT-0700 (Pacific Daylight Time) ⠹ Updating resources in the cloud. This may take a few minutes...
CREATE_IN_PROGRESS IdentityPool AWS::Cognito::IdentityPool Fri Oct 04 2019 23:09:23 GMT-0700 (Pacific Daylight Time) CREATE_COMPLETE UserPoolClientInputs Custom::LambdaCallout Fri Oct 04 2019 23:09:19 GMT-0700 (Pacific Daylight Time) CREATE_IN_PROGRESS UserPoolClientInputs Custom::LambdaCallout Fri Oct 04 2019 23:09:19 GMT-0700 (Pacific Daylight Time) Resource creation Initiated ⠼ Updating resources in the cloud. This may take a few minutes...
CREATE_COMPLETE IdentityPool AWS::Cognito::IdentityPool Fri Oct 04 2019 23:09:25 GMT-0700 (Pacific Daylight Time) CREATE_IN_PROGRESS IdentityPool AWS::Cognito::IdentityPool Fri Oct 04 2019 23:09:24 GMT-0700 (Pacific Daylight Time) Resource creation Initiated ⠋ Updating resources in the cloud. This may take a few minutes...
CREATE_IN_PROGRESS IdentityPoolRoleMap AWS::Cognito::IdentityPoolRoleAttachment Fri Oct 04 2019 23:09:28 GMT-0700 (Pacific Daylight Time) ⠴ Updating resources in the cloud. This may take a few minutes...
CREATE_COMPLETE reframerecomamplifye-dev-20191004225035-authreframerecomamplifye16cd456a-19BSJYQRK36 AWS::CloudFormation::Stack Fri Oct 04 2019 23:09:32 GMT-0700 (Pacific Daylight Time) CREATE_COMPLETE IdentityPoolRoleMap AWS::Cognito::IdentityPoolRoleAttachment Fri Oct 04 2019 23:09:30 GMT-0700 (Pacific Daylight Time) CREATE_IN_PROGRESS IdentityPoolRoleMap AWS::Cognito::IdentityPoolRoleAttachment Fri Oct 04 2019 23:09:30 GMT-0700 (Pacific Daylight Time) Resource creation Initiated ⠧ Updating resources in the cloud. This may take a few minutes...
CREATE_COMPLETE authreframerecomamplifye16cd456a AWS::CloudFormation::Stack Fri Oct 04 2019 23:09:36 GMT-0700 (Pacific Daylight Time) ⠏ Updating resources in the cloud. This may take a few minutes...
CREATE_IN_PROGRESS UpdateRolesWithIDPFunctionOutputs Custom::LambdaCallout Fri Oct 04 2019 23:09:41 GMT-0700 (Pacific Daylight Time) CREATE_COMPLETE UpdateRolesWithIDPFunction AWS::Lambda::Function Fri Oct 04 2019 23:09:39 GMT-0700 (Pacific Daylight Time) CREATE_IN_PROGRESS UpdateRolesWithIDPFunction AWS::Lambda::Function Fri Oct 04 2019 23:09:39 GMT-0700 (Pacific Daylight Time) Resource creation Initiated CREATE_IN_PROGRESS UpdateRolesWithIDPFunction AWS::Lambda::Function Fri Oct 04 2019 23:09:38 GMT-0700 (Pacific Daylight Time) ⠹ Updating resources in the cloud. This may take a few minutes...
UPDATE_COMPLETE reframerecomamplifye-dev-20191004225035 AWS::CloudFormation::Stack Fri Oct 04 2019 23:09:47 GMT-0700 (Pacific Daylight Time) UPDATE_COMPLETE_CLEANUP_IN_PROGRESS reframerecomamplifye-dev-20191004225035 AWS::CloudFormation::Stack Fri Oct 04 2019 23:09:47 GMT-0700 (Pacific Daylight Time) CREATE_COMPLETE UpdateRolesWithIDPFunctionOutputs Custom::LambdaCallout Fri Oct 04 2019 23:09:45 GMT-0700 (Pacific Daylight Time) CREATE_IN_PROGRESS UpdateRolesWithIDPFunctionOutputs Custom::LambdaCallout Fri Oct 04 2019 23:09:44 GMT-0700 (Pacific Daylight Time) Resource creation Initiated ✔ All resources are updated in the cloud
* Install the Amplify Node modules we’ll be using for Authentication
```shell
npm add aws-amplify aws-amplify-react
- Copy the css for the amplify UI widgets into the proper resource for our app’s
css to be picked up
- Note: I was looking for a better way to do this that is more via configuration. If anyone knows a better way please let me know
cp node_modules/@aws-amplify/ui/dist/style.css resources/public/css/aws-amplify-ui-style.css
Update
resources/public/index.htmlto incorporate that css by adding the following line in the<head>section<link href="css/aws-amplify-ui-style.css" rel="stylesheet" type="text/css">Get the changes into git
git add amplify resources/public/css/aws-amplify-ui-style.css git commit -m "Added and configured Amplify" .gitignore package-lock.json package.json amplify resources/public/index.html resources/public/css- Your application at
http://localhost:8280should still be running fine assuming you still have thelein devprocess running
Update the code to enable the Authenticator
Edit src/cljs/re_frame_re_com_amplify_exp/core.cljs
- Add the following lines to the require block. This is what will import the node js into your Clojurescript
["aws-amplify" :default Amplify :as amp]
["aws-amplify-react" :refer (withAuthenticator)]
["/aws-exports.js" :default aws-exports]
- Add the following def after
dev-setupfunction
This is where you are wrapping the Amplify HOC around your application. The withAuthenticator is the HOC function being pulled in from the Amplify Auth SDK. It ensures that your app only is accessed after authentication and it handles all the Frontend UI and communication with the Backend to implement the full suite of Authentication.
(def root-view
(reagent/adapt-react-class
(withAuthenticator
(reagent/reactify-component views/main-panel) true)))
- Change the function
mount-rootto be:(defn ^:dev/after-load mount-root [] (re-frame/clear-subscription-cache!) (.configure Amplify aws-exports) (re-frame/dispatch-sync [::events/initialize-db]) (reagent/render [root-view] (.getElementById js/document "app"))) - Remove the following line from
initfunction:
This makes it so that the re-frame db is inited after the cache is cleared. As far as I can tell the Scaffolding puts it in the wrong place
(re-frame/dispatch-sync [::events/initialize-db])
- The final file should be: ``` clojure (ns amplify_cljs_example.core (:require [reagent.core :as reagent] [re-frame.core :as re-frame] [amplify_cljs_example.events :as events] [amplify_cljs_example.views :as views] [amplify_cljs_example.config :as config] ["aws-amplify" :default Amplify :as amp] ["aws-amplify-react" :refer (withAuthenticator)] ["/aws-exports.js" :default aws-exports] ))
(defn dev-setup [] (when config/debug? (println "dev mode")))
(def root-view (reagent/adapt-react-class (withAuthenticator (reagent/reactify-component views/main-panel) true)))
(defn ^:dev/after-load mount-root [] (re-frame/clear-subscription-cache!) (.configure Amplify aws-exports) (re-frame/dispatch-sync [::events/initialize-db]) (reagent/render [root-view] (.getElementById js/document "app")))
(defn init [] (dev-setup) (mount-root))
* The display should look like this:


* You should click the button on the debugger to have it be in its own window as it will block the “sign-out” button later

* Commit the changes to git
``` shell
git commit -m "App updated to require Cognito Authenticator before any other operation" src/cljs/re_frame_re_com_amplify_exp/core.cljs
Wrap Up
You now have a template of how to create a basic Re-Frame SPA with authentication from AWS Amplify with almost not coding and without having to set up your own backend authentication infrastructure. You can continue with this to use other AWS Amplify authentication features (Social Provider Federation, Multi-factor auth, etc) as well as the other Amplify services such as graphql access to DynamoDB, Push notifications, etc.).
The next article, AWS Amplify and Clojurescript Re-Frame Part 2: Deploy to Production Cloudfront, will show how to deploy it to "production" on AWS Cloudfront using Amplify Console so that the Re-Frame SPA can be used on the general Internet also without you having to set up any servers yourself.


