1. Visit https://ebookultra.com to download the full version and
explore more ebooks
Full Stack Serverless 1st Edition Nader Dabit
_____ Click the link below to download _____
https://ebookultra.com/download/full-stack-
serverless-1st-edition-nader-dabit/
Explore and download more ebooks at ebookultra.com
2. Here are some suggested products you might be interested in.
Click the link to download
Rails Angular Postgres and Bootstrap Powerful Effective
Efficient Full Stack Web Development 2nd ed Edition David
Bryant Copeland [Copeland
https://ebookultra.com/download/rails-angular-postgres-and-bootstrap-
powerful-effective-efficient-full-stack-web-development-2nd-ed-
edition-david-bryant-copeland-copeland/
Recto Verso Redefining the Sketchbook Nader El-Bizri
https://ebookultra.com/download/recto-verso-redefining-the-sketchbook-
nader-el-bizri/
Knative Cookbook Building Effective Serverless
Applications with Kubernetes and OpenShift 1st Edition
Burr Sutter
https://ebookultra.com/download/knative-cookbook-building-effective-
serverless-applications-with-kubernetes-and-openshift-1st-edition-
burr-sutter/
Back to Full Employment 1st Edition Robert Pollin
https://ebookultra.com/download/back-to-full-employment-1st-edition-
robert-pollin/
3. Challenges Opportunities and Solutions in Structural
Engineering and Construction 1st Edition Nader Ghafoori
https://ebookultra.com/download/challenges-opportunities-and-
solutions-in-structural-engineering-and-construction-1st-edition-
nader-ghafoori/
Revolution and Constitutionalism in the Ottoman Empire and
Iran 1st Edition Nader Sohrabi
https://ebookultra.com/download/revolution-and-constitutionalism-in-
the-ottoman-empire-and-iran-1st-edition-nader-sohrabi/
Hit run The rise and fall of Ralph Nader First Edition
Toledano
https://ebookultra.com/download/hit-run-the-rise-and-fall-of-ralph-
nader-first-edition-toledano/
Web Development with Node and Express Leveraging the
JavaScript Stack 1st Edition Ethan Brown
https://ebookultra.com/download/web-development-with-node-and-express-
leveraging-the-javascript-stack-1st-edition-ethan-brown/
Building a Bankroll Full Ring Edition Pawel Nazarewicz
https://ebookultra.com/download/building-a-bankroll-full-ring-edition-
pawel-nazarewicz/
5. Full Stack Serverless 1st Edition Nader Dabit Digital
Instant Download
Author(s): Nader Dabit
ISBN(s): 9781492059899, 1492059897
Edition: 1
File Details: PDF, 7.47 MB
Year: 2020
Language: english
8. Praise for FullStackServerless
“Nader does a great job both making the case for serverless technologies and walking you
through real-world scenarios. After reading this book and implementing the many sample
projects, you will definitely have the skills you need to take advantage of serverless
technologies and build better apps faster than ever.”
—Brice Wilson, Trainer and Consultant
“Developing a full stack application doesn’t have to be daunting. This book provides an
easy, efficient, and effective way to get your application ready and available to your users.”
—Femi Oladeji, Frontend Developer, Temper
“Full Stack Serverless will get you started with GraphQL, AppSync, and cloud
development in no time, handling most of the complexity for you so you can focus on
creating your app. Thumbs up!”
—Oliver Kiessler, Full Stack Developer
“Nader is bringing serverless web development to the masses. Full Stack Serverless is a
can’t-miss book for any web developer interested in using AWS Lambda, Cognito, and
AppSync to improve their work.”
—Adam Rackis, Software Engineer, Riot Games
10. Nader Dabit
Full Stack Serverless
Modern Application Development
with React, AWS, and GraphQL
Boston Farnham Sebastopol Tokyo
Beijing Boston Farnham Sebastopol Tokyo
Beijing
12. Table of Contents
Preface. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xi
1. Full Stack Development in the Era of Serverless Computing. . . . . . . . . . . . . . . . . . . . . . . . 1
Modern Serverless Philosophy 2
Characteristics of a Serverless Application 2
Benefits of a Serverless Architecture 3
Different Implementations of Serverless 5
Introduction to AWS 7
About AWS 7
Full Stack Serverless on AWS 8
Amplify CLI 8
Introduction to the AWS Amplify CLI 10
Installing and Configuring the Amplify CLI 11
Initializing Your First Amplify Project 12
Creating and Deploying Your First Service 14
Deleting the Resources 16
Summary 16
2. Getting Started with AWS Amplify. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
Creating and Deploying a Serverless Function 20
Creating the React Application and Installing the Dependencies 21
Creating a New Serverless Function with the Amplify CLI 21
Walking Through the Code 22
Creating the /coins Route 23
Adding the API 23
Creating a New API 24
Deploying the API and the Lambda Function 24
Interacting with the New API 25
v
13. Configuring the Client App to Work with Amplify 25
The Amplify Client API Category 25
Calling the API and Rendering the Data in React 26
Updating the Function to Call Another API 27
Installing Axios 27
Updating the Function 28
Updating the Client App 29
Summary 30
3. Creating Your First App. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
Introduction to GraphQL 31
What Is GraphQL? 31
What Makes Up a GraphQL API? 32
GraphQL Operations 33
Creating the GraphQL API 34
Viewing and Interacting with the GraphQL API 36
Building the React Application 38
Listing Notes (GraphQL Query) 38
Creating Notes (GraphQL Mutation) 42
Deleting Notes (GraphQL Mutation) 45
Updating Notes (GraphQL Mutation) 46
Real-Time Data (GraphQL Subscriptions) 48
Summary 49
4. Introduction to Authentication. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
Introduction to Amazon Cognito 52
How Amazon Cognito Works 52
Amazon Cognito Integration with AWS Amplify 53
Creating the React App and Adding Amplify 53
Client Authentication Overview 54
Building the App 55
Creating the File and Folder Structure 55
Creating the First Component 56
Public Component 56
Nav Component 57
Protected Component 58
Router Component 59
Profile Component 60
Styling the UI Components 61
Configuring the App 62
Testing the App 62
Summary 62
vi | Table of Contents
14. 5. Custom Authentication Strategies. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
Creating the protectedRoute Hook 63
Creating the Form 65
SignIn Component 68
SignUp Component 68
ConfirmSignUp Component 69
ForgotPassword Component 70
ForgotPasswordSubmit Component 70
Completing Form.js 71
updateForm Helper Function 73
renderForm Function 73
Form Type Toggles 75
Updating the Profile Component 76
Testing the App 77
Summary 77
6. Serverless Functions In-Depth: Part 1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
Event Sources and Data Structure 80
API Gateway Event 80
Amazon S3 Event 81
Amazon Cognito Event 82
IAM Permissions and Trigger Configuration 83
Creating the Base Project 83
Adding a Post-Confirmation Lambda Trigger 84
Dynamic Image Resizing with AWS Lambda and Amazon S3 86
Adding the Custom Logic for Resizing the Image 87
Uploading Images from the React Application 88
Summary 90
7. Serverless Functions In-Depth: Part 2. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
What We’ll Build 91
Getting Started 92
Adding Authentication and Group Privileges 93
Adding the Database 94
Adding the API 95
Creating the Frontend 100
Container Component 101
checkUser Function 101
Nav Component 102
Profile Component 103
Router Component 104
Admin Component 105
Table of Contents | vii
15. Main Component 106
Testing It Out 108
Summary 108
8. AWS AppSync In-Depth. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
Building Skills for GraphQL, AppSync API, and React Router 109
Relationships Between GraphQL Types 110
Multiple Authentication Types 111
Authorization 112
Custom Data Access Patterns Using GSIs 113
Starting to Build the App 113
Creating the Amplify App and Adding the Features 113
Building the Backend 114
Authentication 114
The AppSync API 115
Deploying the Services 117
Building the Frontend 117
Container 118
Footer 118
Nav 119
Admin 119
Router 120
Performance 121
Home 123
Summary 126
9. Building Offline Apps with Amplify DataStore. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
About Amplify DataStore 128
Amplify DataStore Overview 128
Amplify DataStore Operations 128
DataStore Predicates 129
Building an Offline and Real-Time App with Amplify DataStore 130
Creating the Base Project 131
Creating the API 131
Writing the Client-Side Code 132
Testing the Offline Functionality 135
Testing the Real-Time Functionality 135
Summary 135
10. Working with Images and Storage. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137
Using Amazon S3 137
Creating the Base Project 139
viii | Table of Contents
18. Preface
Why I Wrote This Book
When I first learned how to code I had no idea how broad of a spectrum software
development was. All I wanted to do was to build an app. Oh boy, I learned how naive
I was at that time once I started digging into and piecing together all of the things that
it took to accomplish what I wanted to do.
One of the main things I learned was that applications typically consisted of two main
parts: frontend (or client-side code) and backend APIs and services. At the time,
cloud technologies were in their infancy and learning how to build full stack applica‐
tions was overwhelming to say the least! This was made even harder because I wanted
to build native mobile apps, and I learned that building mobile apps was much
tougher to get started with than building web applications.
Fast-forward almost 10 years and the landscape is starting to look much different.
Things that once took a large team of developers to do can now sometimes be accom‐
plished by a single developer. Tools like React Native, Flutter, and Cordova allow
developers to build and ship cross-platform mobile applications using a single code‐
base. Cloud technologies like AWS Amplify, Firebase, and others allow the same
developers to also leverage the cloud to build out the backends much more rapidly
than ever before.
I think we are coming into a new paradigm where it is easier than ever to become a
full stack developer and the definition of what a full stack developer is is starting to
change. I wrote this book to lay out my vision of what this new paradigm looks like in
practice and to showcase a technology that has been created specifically to take
advantage of the most cutting-edge frontend and cloud technologies. What I am
describing in this book is, in my opinion, the future of software engineering.
xi
19. Who This Book Is For
This book is for any software engineer looking to build full stack applications, espe‐
cially those interested in cloud computing. It is also aimed at frontend developers
looking to learn how to use their existing skill set to build full stack applications using
cloud technologies.
It is also a good resource for CTOs and startup founders looking to maximize effi‐
ciency and move with the most developer velocity possible while using the fewest
resources. The techniques outlined in this book are ideal for rapid prototyping and
fast experimentation, allowing developers and founders to get their idea to market
quickly and have a product that is also scalable and durable should it succeed.
How This Book Is Organized
The goal of this book is to introduce you to all of the pieces needed to build a real-
world and scalable full stack application using React and serverless technologies. It
gradually introduces features (like authentication, APIs, and databases) and some
techniques to implement these features, both on the frontend and backend, by build‐
ing out different applications in each chapter.
Each application you create will build upon knowledge learned in the previous chap‐
ter. In the last chapter, you will build out a sophisticated application utilizing many of
the cloud services needed to build real-world applications in your job or startup.
When you have finished working through this book, you should have the knowledge
and understanding needed to apply what you have learned to build serverless applica‐
tions on your own using React and AWS cloud technologies.
Chapter 1, Full Stack Development in the Era of Serverless Computing
In this chapter, I’ll describe serverless philosophy, the characteristics and benefits
of serverless applications, and introduce you to AWS and AWS Amplify CLI.
Chapter 2, Getting Started with AWS Amplify
In this chapter, we will get going using AWS Amplify to create and deploy a serv‐
erless function. We’ll create the function, then add the API and interact with it.
Chapter 3, Creating Your First App
Here, we’ll cover the basic process of creating a new full stack application from
scratch by building a notes app. We will create a new React application, initialize
a new Amplify project, add a GraphQL API, and then connect to and interact
with the API from the client (React) application.
xii | Preface
20. Chapter 4, Introduction to Authentication
In this chapter, we will walk through the process of adding authentication to an
application. We will start by creating a new React application and adding basic
authentication using the withAuthenticator higher-order component (HOC)
from the AWS Amplify React library. We’ll read the user’s metadata and create a
profile screen that will allow the user to see their information.
Chapter 5, Custom Authentication Strategies
In this chapter, we’ll look closer at authentication by creating a custom authenti‐
cation flow with React, React Router, and AWS Amplify. The app will have a sign-
up screen, a sign-in screen, and a forgotten-password screen. Once logged in,
there will be a main menu that will allow them to navigate to their profile page, a
map page, and a welcome screen that will serve as the main view of the app.
Chapter 6, Serverless Functions In-Depth: Part 1 and Chapter 7, Serverless Functions
In-Depth: Part 2
Here, we’ll introduce serverless functions and how to interact with them in a
React application. We’ll walk through how to create, update, and delete serverless
functions by creating an app that fetches shiba inu pictures from a CORS-
protected API with our code living in an AWS Lambda function that we will cre‐
ate and configure using the AWS Amplify CLI.
Chapter 8, AWS AppSync In-Depth
In this chapter, we’ll build upon what we learned in Chapter 3 by building a more
complex API that includes many-to-many relationships and multiple authoriza‐
tion types. We’ll build an event application that allows admins to create stages
and performances. We’ll enable all users to be able to read event information
regardless whether they are signed in, but we’ll only allow admin users who are
signed in to create, update, or delete events and stages.
Chapter 9, Building Offline Apps with Amplify DataStore
In this chapter, we’ll cover how to add offline functionality using Amplify
DataStore.
Chapter 10, Working with Images and Storage
Here, we’ll learn how to create a photo-sharing app that will allow users to
upload and view images.
Chapter 11, Hosting: Deploying Your Application to
the Amplify Console with CI and CD
In this final chapter, we’ll take the photo-sharing app we created in Chapter 10
and deploy it to a live domain using the Amplify Console. We’ll learn how to add
continuous integration (CI) and continuous deployment (CD) by kicking off new
Preface | xiii
21. builds when updates are merged to the master branch. Finally, we’ll learn how to
add a custom domain so your app will be live on a real URL that you own.
Conventions Used in This Book
The following typographical conventions are used in this book:
Italic
Indicates new terms, URLs, email addresses, filenames, and file extensions.
Constant width
Used for program listings, as well as within paragraphs to refer to program ele‐
ments such as variable or function names, databases, data types, environment
variables, statements, and keywords.
Constant width bold
Shows commands or other text that should be typed literally by the user.
Constant width italic
Shows text that should be replaced with user-supplied values or by values deter‐
mined by context.
This element signifies a tip or suggestion.
This element signifies a general note.
Using Code Examples
Supplemental material (code examples, exercises, etc.) is available for download at
https://github.com/dabit3/full-stack-serverless-code.
If you have a technical question or a problem using the code examples, please send
email to [email protected].
This book is here to help you get your job done. In general, if example code is offered
with this book, you may use it in your programs and documentation. You do not
need to contact us for permission unless you’re reproducing a significant portion of
the code. For example, writing a program that uses several chunks of code from this
xiv | Preface
22. book does not require permission. Selling or distributing examples from O’Reilly
books does require permission. Answering a question by citing this book and quoting
example code does not require permission. Incorporating a significant amount of
example code from this book into your product’s documentation does require
permission.
We appreciate, but generally do not require, attribution. An attribution usually
includes the title, author, publisher, and ISBN. For example: “Full Stack Serverless by
Nader Dabit (O’Reilly). Copyright 2020 Nader Dabit, 978-1-492-05989-9.”
If you feel your use of code examples falls outside fair use or the permission given
above, feel free to contact us at [email protected].
O’Reilly Online Learning
For more than 40 years, O’Reilly Media has provided technol‐
ogy and business training, knowledge, and insight to help
companies succeed.
Our unique network of experts and innovators share their knowledge and expertise
through books, articles, and our online learning platform. O’Reilly’s online learning
platform gives you on-demand access to live training courses, in-depth learning
paths, interactive coding environments, and a vast collection of text and video from
O’Reilly and 200+ other publishers. For more information, visit http://oreilly.com.
How to Contact Us
Please address comments and questions concerning this book to the publisher:
O’Reilly Media, Inc.
1005 Gravenstein Highway North
Sebastopol, CA 95472
800-998-9938 (in the United States or Canada)
707-829-0515 (international or local)
707-829-0104 (fax)
We have a web page for this book, where we list errata, examples, and any additional
information. You can access this page at https://oreil.ly/Full_Stack_Serverless.
Email [email protected] to comment or ask technical questions about this
book.
For news and information about our books and courses, visit http://oreilly.com.
Find us on Facebook: http://facebook.com/oreilly
Preface | xv
23. Follow us on Twitter: http://twitter.com/oreillymedia
Watch us on YouTube: http://www.youtube.com/oreillymedia
Acknowledgments
Thank you to my wife, Lilly, who has steadfastly supported me through my career and
has gone above and beyond to keep our life in order as I worked late nights in the
office and sometimes at home to write this book.
Thank you to my kids, Victor and Eli, who are awesome and my inspiration; I love
you both very much. And thank you to my parents for putting me in a position to be
able to learn things and get second, third, and fourth chances at life.
My thanks go to many groups and individuals: to the the entire AWS Mobile team
who took a chance on hiring me fresh out of a tumultuous consulting career to join
their team, and gave me the opportunity to work with the smartest people I’ve ever
met. To Michael Paris, Mohit Srivastava, Dennis Hills, Adrian Hall, Richard Threl‐
kald, Michael Labieniec, Rohan Deshpande, Amit Patel, and all of my other team‐
mates who have showed me the ropes and helped me learn everything I needed to
learn to get going at my new job. To Russ Davis, Lee Johnson, and SchoolStatus for
giving the opportunity to learn bleeding-edge technology on the job that ultimately
catapulted my career into consulting. To Brian Noah, Nate Lubeck, and my team at
Egood, the first “real” tech job I had, for exposing me to the world of meetups and
conferences as well as what it takes to be a great developer.
xvi | Preface
24. CHAPTER 1
Full Stack Development in the
Era of Serverless Computing
People have typically associated cloud computing with backend development and
DevOps. However, over the past few years, this has started to change. With the rise of
functions as a service (FaaS), combined with powerful abstractions in the form of
managed services, cloud providers have lowered the barrier to entry for developers
new to cloud computing, and for traditionally frontend developers.
Using modern tools, frameworks, and services like Amazon Web Services (AWS)
Amplify and Firebase (among others), a single developer can leverage their existing
skill set and knowledge of a single framework and ecosystem (like JavaScript) to build
scalable full stack applications complete with all of the features that would in the past
have required teams of highly skilled backend and DevOps engineers to build and
maintain.
This book focuses on bridging the gap between frontend and backend development
by taking advantage of this new generation of tools and services using the Amplify
Framework. Here you’ll learn how to build scalable applications in the cloud directly
from your frontend environment using the Amplify Command Line Interface (CLI).
You’ll create and interact with various APIs and AWS services, such as authentication
using Amazon Cognito, cloud storage using Amazon S3, APIs using Amazon API
Gateway and AWS AppSync, and databases using Amazon DynamoDB.
By the final chapter, you will understand how to build real-world full stack applica‐
tions in the cloud leveraging AWS services on the backend and React on the frontend.
You’ll also learn how to use modern APIs from React, like hooks, and functional
components, as well as React Context for global state management.
1
25. 1 Eric Jonas, Johann Schleier-Smith et al. “Cloud Programming Simplified: A Berkeley View on Serverless
Computing” (Feb. 10, 2019), http://www2.eecs.berkeley.edu/Pubs/TechRpts/2019/EECS-2019-3.html.
Modern Serverless Philosophy
The term serverless is commonly associated with FaaS. Though you will find varying
definitions as to what it means, the term has recently grown to encompass more of a
philosophy than a shared definition.
Many times when people talk about serverless, they are really describing how to most
efficiently deliver business value with a focus on writing business logic, instead of
coding supporting infrastructure for your business logic. Adopting a serverless mind‐
set allows you to do this by consciously going out of your way to find and leverage
FaaS, managed services, and smart abstractions, while only building custom solutions
if an existing service just doesn’t yet exist.
More and more companies and developers are taking this approach, as it doesn’t
make sense to reinvent the wheel. With the increase in popularity of this philosophy,
there has also been an explosion of services and tools made available from startups
and cloud providers to provide offerings that simplify backend complexity.
For an academic take on what serverless means, you may wish to read the 2019 paper
written by a group at UC Berkeley, “Cloud Programming Simplified: A Berkeley View
on Serverless Computing,”1
. In this paper, the authors expanded the definition of
serverless:
While cloud functions—packaged as FaaS (Function as a Service) offerings—represent
the core of serverless computing, cloud platforms also provide specialized serverless
frameworks that cater to specific application requirements as BaaS (Backend as a Ser‐
vice) offerings. Put simply, serverless computing = FaaS + BaaS.
Backend as a service (BaaS) typically refers to managed services like databases (Fire‐
store, Amazon DynamoDB), authentication services (Auth0, Amazon Cognito), and
artificial intelligence services (Amazon Rekognition, Amazon Comprehend), among
other managed services. Berkeley’s redefinition of what serverless means underscores
what is happening in the broader spectrum of this discussion as cloud providers
begin to build more and better-managed services and put them in this bucket of
serverless.
Characteristics of a Serverless Application
Now that you understand something about the philosophy around serverless, what
are some of the characteristics of a serverless application? Though you may get vary‐
ing answers as to what serverless is, following are some traits and characteristics that
are generally agreed upon by the industry.
2 | Chapter 1: Full Stack Development in the Era of Serverless Computing
26. Decreased operational responsibilities
Serverless architectures typically allow you to shift more of your operational respon‐
sibilities to a cloud provider or third party.
When you decide to implement FaaS, the only thing you should have to worry about
is the code running in your function. All of the server patching, updating, maintain‐
ing, and upgrading is no longer your responsibility. This goes back to the core of
what cloud computing, and by extension serverless, attempts to offer: a way to spend
less time managing infrastructure and spend more time building features and deliver‐
ing business value.
Heavy use of managed services
Managed services usually assume responsibility for providing a defined set of fea‐
tures. They are serverless in the sense that they scale seamlessly, don’t require any
server operations or need to manage uptime, and, most importantly, are essentially
codeless.
Benefits of a Serverless Architecture
These days there are many ways to architect an application. The decisions that are
made early on will impact not only the application life cycle, but also the develop‐
ment teams and ultimately the company or organization. In this book, I advocate for
building your applications using serverless technologies and methodologies and lay
out some ways in which you can do this. But what are the advantages of building your
application like this, and why is serverless becoming so popular?
Scalability
One of the primary advantages of going serverless is out-of-the-box scalability. When
building your application, you don’t have to worry about what would happen if the
application becomes wildly popular and you onboard a large number of new users
quickly—the cloud provider will handle this for you.
The cloud provider automatically scales your application, running the code in
response to each interaction. In a serverless function, your code runs in parallel and
individually processes each trigger (in turn, scaling with the size of the workload).
Not having to worry about scaling your servers and databases is a great advantage. It’s
one less thing you have to worry about when architecting your application.
Cost
The pricing models of serverless architectures and traditional cloud-based or on-
premises infrastructures differ greatly.
Modern Serverless Philosophy | 3
27. With the traditional approach, you often paid for computing resources whether or
not they were utilized. This meant that if you wanted to make sure your application
would scale, you needed to prepare for the largest workload you thought you might
see regardless of whether you actually reached that point. This approach meant you
were paying for unused resources for the majority of the life of your application.
With serverless technologies, you pay only for what you use. With FaaS, you’re billed
based on the number of requests for your functions, the time it takes for your func‐
tion code to execute, and the reserved memory for each function. With managed
services like Amazon Rekognition, you are only charged for the images processed
and minutes of video processed, etc.—again paying only for what you use.
This allows you to build features and applications with essentially no up-front infra‐
structure costs. Only if your application begins seeing increasing adoption and scal‐
ing do you begin to have to pay for the service.
The bill from your cloud provider is only one part of the total cost of your cloud
infrastructure—there’s also the operations’ salaries. That cost decreases if you have
fewer ops resources.
In addition, building applications in this way usually facilitates a faster time to mar‐
ket, decreasing overall development time and, therefore, development costs.
Developer velocity
With fewer features to build, developer velocity increases. Being able to spin up the
types of features that are typical for most applications (e.g., databases, authentication,
storage, and APIs) allows you to quickly focus on writing the core functionality and
business logic for the features that you want to deliver.
Experimentation
If you are not investing a lot of time building out repetitive features, you are able to
experiment more easily and with less risk.
When shipping a new feature, you often assess the risk (time and money involved
with building the feature) against the possible return on investment (ROI). As the
risk involved in trying out new things decreases, you are free to test out ideas that in
the past may not have seen the light of day.
A/B testing (also known as bucket testing or split testing) is a way to compare multiple
versions of an application to determine which one performs best. Because of the
increase in developer velocity, serverless applications usually enable you to A/B test
different ideas much more quickly and easily.
4 | Chapter 1: Full Stack Development in the Era of Serverless Computing
28. Security and stability
Because the services that you are subscribing to are the core competency of the ser‐
vice provider maintaining them, you are usually getting something that is much more
polished and more secure than you could have built yourself. Imagine that a compa‐
ny’s core business model has been, for many years, the delivery of a pristine authenti‐
cation service, having fixed issues and edge cases for thousands of companies and
customers.
Now, imagine trying to replicate a service like that within your own team or organiza‐
tion. Though this is completely possible, choosing to use a service built and main‐
tained by those whose only job is to build and maintain that exact thing is a safe bet
that will ultimately save you time and money.
Another advantage of using these service providers is that they will strive for the least
amount of downtime possible. This means that they are taking on the burden of not
only building, deploying, and maintaining these services, but also doing everything
they can to make sure that they are stable.
Less code
Most engineers will agree that, at the end of the day, code is a liability. What has value
is the feature that the code delivers, not the code itself. When you find ways to deliver
these features while simultaneously limiting the amount of code you need to main‐
tain, and even doing away with the code completely, you are reducing overall com‐
plexity in your application.
With less complexity comes fewer bugs, easier onboarding for new engineers, and
overall less cognitive load for those maintaining and adding new features. A devel‐
oper can hook into these services and implement features with no knowledge of the
actual backend implementation and with little to no backend code at all.
Different Implementations of Serverless
Let’s take a look at the different ways that you can build serverless applications as well
as some of the differences between them.
Serverless Framework
One of the first serverless implementations, the Serverless Framework, is the most
popular. It is a free and open source framework, launched in October 2015 under the
name JAWS, and written using Node.js. At first, the Serverless Framework only sup‐
ported AWS, but then it added support for cloud providers like Google and Microsoft
Azure, among others.
The Serverless Framework utilizes a combination of a configuration file (server‐
less.yml), CLI, and function code to provide a nice experience for people wanting to
Modern Serverless Philosophy | 5
29. deploy serverless functions and other AWS services to the cloud from a local environ‐
ment. Getting up and running with the Serverless Framework can present a some‐
what steep learning curve, especially for developers new to cloud computing. There is
much terminology to learn and a lot that goes into understanding how cloud services
work in order to build anything more than just a “Hello World” application.
Overall, the Serverless Framework is a good option if you understand to some extent
how cloud infrastructure works, and are looking for something that will work with
other cloud providers in addition to AWS.
The AWS Serverless Application Model
The AWS Serverless Application Model (AWS SAM) is an open source framework,
released November 18, 2016, and built and maintained by AWS and the community.
This framework only supports AWS.
SAM allows you to build serverless applications by defining the API Gateway APIs,
AWS Lambda functions, and Amazon DynamoDB tables needed by your serverless
application in YAML files. It uses a combination of YAML configuration and function
code and a CLI to create, manage, and deploy serverless applications.
One advantage of SAM is that it is an extension of AWS CloudFormation, which is
very powerful and allows you to do almost anything in AWS. This can also be a disad‐
vantage to developers new to cloud computing and not familiar with AWS services,
permissions, roles, and terminology, as you have to already be familiar with how the
services work, the naming conventions to set them up, and how to wire it all together.
SAM is a good choice if you are familiar with AWS and are only deploying your serv‐
erless applications to AWS.
Amplify Framework
The Amplify Framework is a combination of four things: CLI, client library, tool‐
chain, and web-hosting platform. Amplify’s purpose is to provide an easy way for
developers to build and deploy full stack web and mobile applications that leverage
the cloud. It enables not only features such as serverless functions and authentication,
but also GraphQL APIs, machine learning (ML), storage, analytics, push notifica‐
tions, and more.
Amplify provides an easy entry point into the cloud by doing away with terminology
and acronyms that may be unfamiliar to newcomers to AWS and instead uses a
category-name approach for referring to services. Rather than referring to the
authentication service as Amazon Cognito, it’s referred to as auth, and the framework
just uses Amazon Cognito under the hood.
6 | Chapter 1: Full Stack Development in the Era of Serverless Computing
30. How Do the Four Pieces Fit Together?
• The CLI allows you to create, configure, and deploy cloud services from the com‐
mand line.
• The Client library allows you to connect to and interact with these cloud services
from your web or mobile application.
• The toolchain helps facilitate and speed development by doing things like gener‐
ating code and serverless function boilerplates.
• The hosting platform allows you to deploy your application to a live domain
complete with atomic deployments, continuous integration (CI), continuous
deployment (CD), custom domains, and more.
Other options
More companies have started providing abstractions over serverless functions, usu‐
ally intending to improve the negative user experience traditionally associated with
working directly with AWS Lambda. A few popular options among these are Apex,
Vercel, Cloudflare Workers, and Netlify Functions.
Many of these tools and frameworks still actually use AWS or some other cloud pro‐
vider under the hood, so you are essentially going to be paying more in exchange for
what they argue is a better user experience. Most of these tools do not offer much of
the other suite of services available from AWS or other cloud providers; things like
authentication, AI and ML services, complex object storage, and analytics may or
may not be part of their offerings.
If you are interested in learning other ways of developing serverless applications, I
would recommend checking out these options.
Introduction to AWS
In this section, I’ll give an overview of AWS and talk about why something like the
Amplify Framework exists.
About AWS
AWS, a subsidiary of Amazon, was the first company to provide on-demand cloud
computing platforms to developers. It first launched in 2004 with a single service:
Amazon Simple Queue Service (Amazon SQS). In 2006, they officially relaunched
with a total of three services: Amazon SQS, Amazon S3, and Amazon EC2. Since
2006, AWS has grown and remains the largest cloud computing provider in the
Introduction to AWS | 7
31. world, continuing to add services every year. AWS now offers more than two hun‐
dred services.
With the current state of cloud computing moving more toward serverless technolo‐
gies, the barrier to entry is being lowered. However, it is still often tough for either a
frontend developer or someone new to cloud computing to get started.
With this new serverless paradigm, AWS saw an opportunity to create a framework
that focused on enabling these traditionally frontend developers and developers new
to cloud computing to get started building cloud applications.
Full Stack Serverless on AWS
Full stack serverless is about providing developers with everything needed on both
ends of the stack to accomplish their objective of building scalable applications as
quickly as possible. Here, we’ll look at how you can build applications in this way
using AWS tools and services.
Amplify CLI
If you’re starting out with AWS, the sheer number of services can be overwhelming.
In addition to the many services to sort between, each service often has its own steep
learning curve. To help ease this, AWS has created the Amplify CLI.
The Amplify CLI provides an easy entry point for developers wanting to build appli‐
cations on AWS. The CLI allows developers to create, configure, update, and delete
cloud services directly from their frontend environment.
Instead of a service-name approach (as used by the AWS Console and many other
tools, like CloudFormation), the CLI takes a category-name approach. AWS has many
service names (for example, Amazon S3, Amazon Cognito, and Amazon Pinpoint),
which can be confusing to new developers. Rather than using the service names to
create and configure these services, the CLI uses names like storage (Amazon S3),
auth (Amazon Cognito), and analytics (Amazon Pinpoint) to give you a way to
understand what the service actually does versus simply giving the service name.
The CLI has a host of commands that allow you to create, update, configure, and
remove services without having to leave your frontend environment. You can also
spin up and deploy new environments using the CLI in order to test out new features
without affecting the main environment.
Once you’ve created and deployed features using the CLI, you can then use the
Amplify client libraries to begin interacting with the services from your client-side
application.
8 | Chapter 1: Full Stack Development in the Era of Serverless Computing
32. Amplify client
Building full stack applications requires a combination of both client-side tooling and
backend services. In the past, the main way to interact with AWS services was using
an AWS software development kit (SDK) such as Java, .NET, Node.js, and Python.
These SDKs work well, but none of them are particularly well-suited for client-side
development. Before Amplify, there was no simple method for building client-side
applications using AWS. If you look at the documentation for the AWS Node.js SDK,
you’ll also notice that it presents a steep learning curve for developers new to AWS.
The Amplify client is a library made especially to provide an easy-to-use API for Java‐
Script applications that need to interact with AWS services. Amplify also has client
SDKs for React Native, native iOS, and native Android.
The approach that the Amplify client takes is to provide a higher level of abstraction
and bake in best practices to provide a declarative, easy-to-use API. At the same time,
it gives you full control over the interactions with your backend. It’s also built espe‐
cially with the client in mind, with features like WebSocket and GraphQL subscrip‐
tion support. It utilizes localStorage for the browser and AsyncStorage for React
Native to store security tokens like IdTokens and AccessTokens to persist user
authentication.
Amplify also provides UI components for popular frontend and mobile frameworks
including React, React Native, Vue, Angular, Ionic, native Android, and native iOS.
These framework-specific components allow you to quickly get up and running with
common features like authentication and complex object storage and retrieval
without having to build out the frontend UI and deal with state.
The Amplify Framework does not support the entire suite of AWS services; instead, it
supports a subset of them with almost all of them falling into the category of server‐
less. Using Amplify, it wouldn’t make much sense to offer support for interacting with
with EC2, but it makes a lot of sense to offer support for working with Representa‐
tional State Transfer (REST) and GraphQL APIs.
Amplify was created as an end-to-end solution to fill a previously unfilled gap, but it
also encompasses a new way to build full stack cloud applications.
AWS AppSync
AWS AppSync is a managed API layer that uses GraphQL to make it easy for applica‐
tions to interact with any data source, REST API, or microservice.
The API layer is one of the most important parts of an application. Modern applica‐
tions typically interact with a large number of backend services and APIs; things like
databases, managed services, third-party APIs, and storage solutions, among others.
Microservice architecture is the usual term used for a large application built using a
combination of modular components or services.
Introduction to AWS | 9
33. Most services and APIs will have varying implementation details, which creates a
challenge when you’re working with a microservice architecture. This leads to incon‐
sistent and sometimes messy code, as well as more cognitive load on the frontend
developers making requests to these APIs.
One good approach to working with a microservice architecture is to provide a con‐
sistent API gateway layer that then takes all of the requests and forwards them on to
the backend services. This allows a consistent interaction layer for your client to
interact with, making development easier on the frontend.
GraphQL, a technology created and open sourced by Facebook, offers an especially
good abstraction for creating an API gateway. GraphQL introduces a defined and
consistent specification for interacting with APIs in the form of three operations:
queries (reads), mutations (writes/updates), and subscriptions (real-time data). These
operations are defined as part of a main schema that also provides a contract between
the client and the server in the form of GraphQL types. GraphQL operations are not
bound to any specific data source, so you as a developer are free to use them to inter‐
act with anything from a database, an HTTP endpoint, a microservice, or even a serv‐
erless function.
Typically, when building a GraphQL API, you need to deal with building, deploying,
maintaining, and configuring your own API. With AWS AppSync, you can instead
offload the server and API management as well as the security to AWS.
Modern applications often also have concerns such as real-time and offline support.
Another benefit of AppSync is that it has built-in support for offline (Amplify client
SDKs) as well as real time (GraphQL subscriptions) to enable developers to build
these types of applications.
In this book, you will be using AWS AppSync along with various data sources (like
DynamoDB for NoSQL and AWS Lambda for serverless functions) as the main API
layer.
Introduction to the AWS Amplify CLI
You will be using Amplify CLI throughout this book to create and manage your cloud
services. To learn how it works, you’ll be creating and deploying a service using the
CLI in this section. Once the service is deployed, you’ll also learn how to remove it
and then delete any backend resources associated with the deployment. Let’s take a
look at how you can create your first service.
10 | Chapter 1: Full Stack Development in the Era of Serverless Computing
34. Installing and Configuring the Amplify CLI
To get started, you first need to install and configure the Amplify CLI:
~ npm install -g @aws-amplify/cli
To use the CLI, you will first need to have Node.js version 10.x or
greater and npm version 5.x or greater installed on your machine.
To install Node.js, I recommend either visiting the Node.js installa‐
tion page and following the installation instructions or using Node
Version Manager (NVM).
After the CLI has been installed, you next need to configure it with an identity and
access management (IAM) user in your AWS account. To do so, you’ll configure the
CLI with a reference to a set of user credentials (access key ID and secret access key).
Using these credentials, you’ll be able to create AWS services on behalf of this user
directly from the CLI.
To create a new user and configure the CLI, you’ll run the configure command:
~ amplify configure
This will walk you through the following steps:
1. Specify the AWS region.
This will allow you to choose the region in which you’d like to create your user
(and, by extension, the services associated with this user). Choose the region
closest to you or a preferred region.
2. Specify the username.
This name will be the local reference of the user that you will be creating in your
AWS account. I suggest using a name that you’ll be able to recognize later when
referencing it, such as amplify-cli-us-east-1-user or mycompany-cli-admin.
Once you enter your name, the CLI will open up the AWS IAM dashboard. From
here, you can accept the defaults by clicking Next: Permissions, Next: Tags, Next:
Review, and Create user to create the IAM user.
In the next screen, you will be given the IAM user credentials: the access key ID and
secret access key. See Figure 1-1.
Introduction to the AWS Amplify CLI | 11
35. Figure 1-1. AWS IAM dashboard
Back in the CLI, paste in the values for the access key ID and secret access key. Now
you’ve successfully configured the CLI and you can begin creating new services.
Initializing Your First Amplify Project
Now that the CLI has been installed and configured, you can create your first project.
This step is usually done within the root of your client application. Since you will be
using React for most of this book, we’ll start by initializing a new React project:
~ npx create-react-app amplify-app
# after creating the React app, change into the new directory
~ cd amplify-app
Now you need to install the Amplify that you’ll be using on the client. The libraries
you’ll be using are AWS Amplify and AWS Amplify React for the React-specific UI
components:
~ npm install aws-amplify @aws-amplify/ui-react
Next, you can create an Amplify project. To do so, you’ll run the init command:
~ amplify init
This will walk you through the following steps:
1. Enter a name for the project.
This will be the local name for the project, usually something that describes what
the project is or what it does.
2. Enter a name for the environment.
This will be a reference to the initial environment that you will be working in.
Typical environments in this workflow could be something like dev, local, or prod
but could be anything that makes sense to you.
12 | Chapter 1: Full Stack Development in the Era of Serverless Computing
36. 3. Choose your default editor.
This will set your editor preference. The CLI will later use this preference to open
your text editor with files that are part of the current project.
4. Choose the type of app that you’re building.
This will determine whether the CLI should configure, build, and run commands
if you are using JavaScript. For this example, choose javascript.
5. What JavaScript framework are you using?
This will determine a few base build and start commands. For this example,
choose react.
6. Choose your source directory path.
This allows you to set the directory where your source code will live. For this
example, choose src.
7. Choose your distribution directory path.
For web projects, this will be the folder containing the complied JavaScript source
code as well as your favicon, HTML, and CSS files. For this example, choose
build.
8. Choose your build command.
This specifies the command for compiling and bundling your JavaScript code.
For this example, use npm run-script build.
9. Choose your start command.
This specifies the command to server your application locally. For this example,
use npm run-script start.
10. Do you want to use an AWS profile?
Here, choose Y and then pick the AWS profile you created when you ran amplify
configure.
Now, the Amplify CLI will initialize your new Amplify project. When the initializa‐
tion is complete, you will have two additional resources created for you in your
project: a file called aws-exports located in the src directory and a folder named
amplify located in your root directory.
The aws-exports file
The aws-exports file is a key-value pairing of the resource categories created for
you by the CLI along with their credentials.
The amplify folder
This folder holds all of the code and configuration files for your Amplify project.
In this folder you’ll see two subfolders: the backend and #current-cloud-backend
folders.
Introduction to the AWS Amplify CLI | 13
37. The backend folder
This folder contains all of the local code for your project such as the
GraphQL schema for an AppSync API, the source code for any serverless
functions, and infrastructure as code representing the current local status of
the Amplify project.
The #current-cloud-backend folders
This folder holds the code and configurations that reflect what resources
were deployed in the cloud with your last Amplify push command. It helps
the CLI differentiate between the configuration of the resources already pro‐
visioned in the cloud and what is currently in your local backend directory
(which reflects your local changes).
Now that you’ve initialized your project, you can add your first cloud service:
authentication.
Creating and Deploying Your First Service
To create a new service, you can use the add command from Amplify:
~ amplify add auth
This will walk you through the following steps:
1. Do you want to use the default authentication and security configuration?
This gives you the option of creating an authentication service using a default
configuration (MFA on sign-up, password at sign-in), creating an authentication
configuration with social providers, or creating a completely custom authentica‐
tion configuration. For this example, choose Default configuration.
2. How do you want users to be able to sign in?
This will allow you to specify the required sign-in property. For this example,
accept the default by choosing Username.
3. Do you want to configure advanced settings?
This will allow you to walk through additional advanced settings for things like
additional sign-up attributes and Lambda triggers. You do not need any of these
for this example, so accept the default by choosing No, I am done.
Now, you’ve successfully configured the authentication service and are now ready
to deploy. To deploy the authentication service, you can run the push command:
~ amplify push
4. Are you sure you want to continue?
Choose Y.
14 | Chapter 1: Full Stack Development in the Era of Serverless Computing
38. After the deployment is complete, your authentication service has successfully been
created. Congratulations, you’ve deployed your first feature. Now, let’s test it out.
There are several ways to interact with the authentication service in a React applica‐
tion. You can use the Auth class from Amplify, which has over 30 methods available
(methods like signUp, signIn, signOut, etc.), or you can use the framework-specific
components like withAuthenticator that will scaffold out an entire authentication
flow, complete with preconfigured UI. Let’s try out the withAuthenticator higher-
order (HOC) component.
First, configure the React app to work with Amplify. To do so, open src/index.js and
add the following code below the last import statement:
import Amplify from 'aws-amplify'
import config from './aws-exports'
Amplify.configure(config)
Now, the app has been configured and you can begin interacting with the authentica‐
tion service. Next, open src/App.js and update the file with the following code:
import React from 'react'
import { withAuthenticator, AmplifySignOut } from '@aws-amplify/ui-react'
function App() {
return (
<div>
<h1>Hello from AWS Amplify</h1>
<AmplifySignOut />
</div>
)
}
export default withAuthenticator(App)
At this point, you can test it out by launching the app:
~ npm start
Now, your app should be launched with the preconfigured authentication flow in
front of it. See Figure 1-2.
Introduction to the AWS Amplify CLI | 15
39. Figure 1-2. withAuthenticator HOC component
Deleting the Resources
Once you no longer need a feature or a project, you can remove it using the CLI.
To remove an individual feature, you can run the remove command:
~ amplify remove auth
To delete an entire Amplify project along with all of the corresponding resources that
have been deployed in your account, you can run the delete command:
~ amplify delete
Summary
Cloud computing is growing at a rapid pace as more and more companies have come
to rely on the cloud for the majority of their workloads. With this growth in usage,
knowledge of cloud computing is becoming a valuable addition to your skill set.
The paradigm of serverless, a subset of cloud computing, is also rapidly growing in
popularity among business users, as it offers all of the benefits of cloud computing
while also featuring automatic scaling, while needing little to no maintenance.
16 | Chapter 1: Full Stack Development in the Era of Serverless Computing
40. Tools like the Amplify Framework are making it easier for developers of all back‐
grounds to get up and running with cloud as well as serverless computing. In the next
chapters, you’ll learn how to build real-world full stack serverless applications in the
cloud, utilizing cloud services and the Amplify Framework.
Summary | 17
42. CHAPTER 2
Getting Started with AWS Amplify
At the core of most applications is the data/API layer. This layer could look like many
things. In the serverless world, this usually will be composed of a combination of API
endpoints and serverless functions. These serverless functions could be doing some
logic and returning data, interacting with a database of some kind, or even interacting
with another API endpoint.
There are two main ways of creating APIs with Amplify:
• A combination of Amazon API Gateway and a Lambda function
• A GraphQL API connected to some type of data source (database, Lambda func‐
tion, or HTTP endpoint)
API Gateway is an AWS service that allows you to create API endpoints and route
them to different services, often via a Lambda function. When you make an API call,
it will route the request through API Gateway, invoke the function, and return the
response. Using the Amplify CLI, you can create both the API Gateway endpoint as
well as the Lambda function; the CLI will automatically configure the API to be able
to invoke the Lambda function via an HTTP request.
Once your API is created, you then need a way to interact with it. Using the Amplify
client you will be able to send requests to the endpoint using the Amplify API class.
The API class allows you to interact with both GraphQL APIs as well as API Gateway
endpoints, as shown in Figure 2-1.
In this chapter, you’ll create your first full stack serverless app that will interact with a
serverless function via an API Gateway endpoint. You’ll use the CLI to create an API
endpoint as well as a serverless function, and then use the Amplify client libraries to
interact with the API.
19
43. Figure 2-1. API with Lambda
At first, the app will fetch a hardcoded array of items from the function. You’ll then
learn how to update the function to make an asynchronous HTTP request to another
API to retrieve data and return it to the client.
Creating and Deploying a Serverless Function
At the core of many serverless applications are serverless functions. Serverless func‐
tions run your code in stateless compute containers that are event-driven, short-lived
(may last for one invocation), and fully managed by the cloud provider of your
choice. These functions scale seamlessly and do not require any server operations.
While most people think of serverless functions as being invoked or triggered by an
API call, these functions can also be triggered by a variety of different events. In addi‐
tion to HTTP requests, a few popular ways to invoke a serverless function are via an
image upload to a storage service, a database operation (like create, update, or delete),
or even from another serverless function.
Serverless functions scale automatically, so there’s no need to worry about your appli‐
cation if you get a large spike in traffic. The first time you invoke a function, the ser‐
vice provider will create an instance of the function and run its handler method to
process the event. After the function finishes and returns a response, it will remain
and process additional events if they come in. If another invocation happens while
the first event is still processing, the service will then create another instance.
Serverless functions also have a payment model that is different from traditional
infrastructure. With services like AWS Lambda, you only pay for what you use and
are charged based on the number of requests for your functions and the time it takes
for your code to execute. This is in contrast to provisioning and paying for infrastruc‐
ture like servers regardless of whether they are being utilized.
20 | Chapter 2: Getting Started with AWS Amplify
44. Now that you know about serverless functions, let’s take a look at how you can create
a serverless function and hook it up to an API that will invoke it from an HTTP
request.
Creating the React Application and Installing the Dependencies
To get started, you’ll first need to create the React application. To do so, you can use
npx:
~ npx create-react-app amplify-react-app
~ cd amplify-react-app
Next, you will need to install the dependencies. For this app, you’ll only need the
AWS Amplify library:
~ npm install aws-amplify
After installing the dependencies, you can now initialize a new Amplify project in the
root of the React application:
~ amplify init
? Enter a name for the project: cryptoapp
? Enter a name for the environment: local
? Choose your default editor: <your-preferred-editor>
? Choose the type of app that you're building: javascript
? What javascript framework are you using: react
? Source Directory Path: src
? Distribution Directory Path: build
? Build Command: npm run-script build
? Start Command: npm run-script start
? Do you want to use an AWS profile? Here, choose *Y* and pick the AWS
profile you created when you ran `amplify configure`.
Now, both the Amplify project and the React app have been successfully created and
you can begin adding new features.
Creating a New Serverless Function with the Amplify CLI
In the next step, we’ll create the serverless function that you will be using for this app.
The app you are building in this chapter is a cryptocurrency app. At first, you will
hardcode an array of cryptocurrency information in the function and return it to the
client. Later in this chapter, you’ll update this function to call another API (CoinLore)
and asynchronously fetch and return data.
To create the function, run the following command:
~ amplify add function
? Select which capability you want to add: Lambda function
? Provide a friendly name for your resource to be used as a label for
Creating and Deploying a Serverless Function | 21
45. this category in the project: cryptofunction
? Provide the AWS Lambda function name: cryptofunction
? Choose the function runtime that you want to use: NodeJS
? Choose the function template that you want to use: Serverless express
function (Integration with Amazon API Gateway)
? Do you want to access other resources created in this project from
your Lambda function? No
? Do you want to invoke this function on a recurring schedule? No
? Do you want to configure Lambda layers for this function? No
? Do you want to edit the local Lambda function now? No
If the function has successfully been created, you should see a mes‐
sage saying “Successfully added resource cryptofunction locally.”
You should now see a new subfolder located within the amplify directory at amplify/
backend/function/cryptofunction.
Walking Through the Code
When you created this resource, a new folder in amplify/backend was created named
function. All of the functions created by the CLI will be stored in this folder. For now,
you only have a single function, cryptofunction. In the cryptofunction folder, you
will see a couple of configuration files as well as an src directory where the main func‐
tion code is located.
Serverless functions are essentially just encapsulated applications running on their
own. Because the function you created is in JavaScript, you’ll see that there are all of
the things you’d typically see in any JavaScript application, including package.json and
index.js files.
Next, have a look at the function entry point located at src/index.js, in the cryptofunc‐
tion folder. In this file you’ll see that there is a function called exports.handler. This
is the entry point for the function invocation. When the function is invoked, this is
the code that is run.
You can handle the event directly in this function if you would like, but since you will
be working with an API, a more useful way to do this is to proxy the path into an
express app with routing (i.e., http://yourapi/<somepath>). Doing this gives you mul‐
tiple routes in a single function as well as multiple HTTP request methods like get,
put, post, and delete for each route. The serverless express framework provides an
easy way to do this and has been built into the function boilerplate for you.
In index.js, you will see a line of code that looks like this:
awsServerlessExpress.proxy(server, event, context);
22 | Chapter 2: Getting Started with AWS Amplify
46. This code is where the event, context, and path are proxied to the express server run‐
ning in app.js.
In app.js, you will then be able to create HTTP requests against whatever routes you
create for your API (this example being a /coins route to fetch cryptocurrency).
Creating the /coins Route
Now that you have seen how the application is structured, let’s create a new route in
app.js and return some data from it. The route that you will be creating is a /coins
route. This route will be returning an object containing a coins array.
Let’s add the new route. Before the first app.get('/items') route, add the following
code:
/* amplify/backend/function/cryptofunction/src/app.js /*
app.get('/coins', function(req, res) {
const coins = [
{ name: 'Bitcoin', symbol: 'BTC', price_usd: "10000" },
{ name: 'Ethereum', symbol: 'ETH', price_usd: "400" },
{ name: 'Litecoin', symbol: 'LTC', price_usd: "150" }
]
res.json({
coins
})
})
This new route has a hardcoded array of cryptocurrency information. When the
function is invoked with this route, it will respond with an object containing a single
property named coins that will contain the coins array.
Adding the API
Now that the function is created and configured, let’s put an API in front of it so you
can trigger it with an HTTP request.
To do this, you will be using Amazon API Gateway. API Gateway is a fully managed
service that enables developers to create, publish, maintain, monitor, and secure
REST and WebSocket APIs. API Gateway is one of the services supported by both the
Amplify CLI as well as the Amplify client library.
In this section, you’ll create a new API Gateway endpoint and configure it to invoke
the Lambda function you created in the previous section.
Adding the API | 23
47. Creating a New API
To create the API, you can use the Amplify add command. From the root of the
project, run the following command in your terminal:
~ amplify add api
? Please select from one of the below mentioned services: REST
? Provide a friendly name for your resource to be used as a label for
this category in the project: cryptoapi
? Provide a path: /coins
? Choose a Lambda source: Use a Lambda function already added in the
current Amplify project
? Choose the Lambda function to invoke by this path: cryptofunction
? Restrict API access: N
? Do you want to add another path? N
Deploying the API and the Lambda Function
Now that the function and API have both been created, you need to deploy them to
your account to make them live. To do so, you can run the Amplify push command:
~ amplify push
? Are you sure you want to continue? Y
Once the deployment has successfully completed, the services are live and ready to
use.
You can use the Amplify CLI status command at any time to see the current status of
your project. The status command will list out all of the currently configured serv‐
ices in your project and give you the status for each of them:
~ amplify status
Current Environment: local
| Category | Resource name | Operation | Provider plugin |
| -------- | -------------- | --------- | ----------------- |
| Function | cryptofunction | No Change | awscloudformation |
| Api | cryptoapi | No Change | awscloudformation |
The main thing to notice in this status output is the Operation. The Operation tells
you what will happen the next time push is run in the project. The Operation prop‐
erty will be set to Create, Update, Delete, or No Change.
24 | Chapter 2: Getting Started with AWS Amplify
48. Interacting with the New API
Now that the resources have been deployed, you can begin interacting with the API
from the React application.
Configuring the Client App to Work with Amplify
To use the Amplify client library in any application, there is a base configuration that
needs to be set up, usually at the root level. When you create the resources, the CLI
populates the aws-exports.js file with information about your resources. You will use
this file to configure the client application to work with Amplify.
To configure the app, open src/index.js and add the following below the last import:
import Amplify from 'aws-amplify'
import config from './aws-exports'
Amplify.configure(config)
The Amplify Client API Category
After the client application has been configured, you can begin interacting with your
resources.
The Amplify client library has various API categories that can be imported and used
for various types of functionality, including Auth for authentication, Storage for stor‐
ing items in S3, and API for interacting with REST and GraphQL APIs.
In this section, you will be working with the API category. API has various methods
available—including API.get, API.post, API.put, and API.del—for interacting with
REST APIs, and API.graphql for interacting with GraphQL APIs.
When working with a REST API, API takes in three arguments:
API.get(apiName: String, path: String, data?: Object)
apiName
The name given when you create the API from the command line. In our exam‐
ple, this value would be cryptoapi.
path
The path that you would like to interact with. In our example, we created /coins,
so the path would be /coins.
data
This is an optional object containing any properties you’d like to pass to the API,
including headers, query string parameters, or a body.
Interacting with the New API | 25
49. In our example, the API call is going to look like this:
API.get('cryptoapi', '/coins')
The API returns a promise, meaning you can handle the call using either a promise
or an async function:
// promise
API.get('cryptoapi', '/coins')
.then(data => console.log(data))
.catch(error => console.log(error))
// async await
const data = await API.get('cryptoapi', '/coins')
In the examples in this book, we’ll be handling promises using async functions.
Calling the API and Rendering the Data in React
Next, let’s call the API and render the data. Update src/App.js with the following:
// Import useState and useEffect hooks from React
import React, { useState, useEffect } from 'react'
// Import the API category from AWS Amplify
import { API } from 'aws-amplify'
import './App.css';
function App() {
// Create coins variable and set to empty array
const [coins, updateCoins] = useState([])
// Define function to all API
async function fetchCoins() {
const data = await API.get('cryptoapi', '/coins')
updateCoins(data.coins)
}
// Call fetchCoins function when component loads
useEffect(() => {
fetchCoins()
}, [])
return (
<div className="App">
{
coins.map((coin, index) => (
<div key={index}>
<h2>{coin.name} - {coin.symbol}</h2>
<h5>${coin.price_usd}</h5>
</div>
))
26 | Chapter 2: Getting Started with AWS Amplify
50. }
</div>
);
}
export default App
Then, run the app:
~ npm start
When the app loads, you should see a list of coins with their name, symbol, and price,
as shown in Figure 2-2.
Figure 2-2. Fetching data from the API
Updating the Function to Call Another API
Next, you’ll update the function to call another API, the CoinLore API, that will
return dynamic data from the CoinLore service. The user will be able to add set filters
like limit and start to limit the number of items coming back from the API.
To get started, you will first need a way to interact with an HTTP endpoint in the
Lambda function. The library you will be using for this lesson is the Axios library.
Axios is a promise-based HTTP client for the browser and Node.js.
Installing Axios
The first thing you need to do is install the Axios package in your function folder in
order to send HTTP requests from the function. Navigate to amplify/backend/func‐
tion/cryptofunction/src, install Axios, and then navigate back to the root of the app:
~ cd amplify/backend/function/cryptofunction/src
~ npm install axios
~ cd ../../../../../
Updating the Function to Call Another API | 27
52. butt of wine. Edward's young sons are presently to be strangled in
prison. Hastings has just been hurried to the scaffold without trial or
form of law. The thing is now to avoid all appearance of complicity in
these crimes, and to seem austerely disinterested with regard to the
crown. To this end he makes his rascally henchman, Buckingham,
persuade the simple-minded and panic-stricken Lord Mayor of
London, with other citizens of repute, to implore him, in spite of his
seeming reluctance, to mount the throne. Buckingham prepares
Richard for their approach (iii. 7):—
"Intend some fear;
Be not you spoke with but by mighty suit:
And look you get a prayer-book in your hand,
And stand between two churchmen, good my lord:
For on that ground I'll make a holy descant:
And be not easily won to our requests;
Play the maid's part, still answer nay, and take it."
Then come the citizens. Catesby bids them return another time. His
grace is closeted with two right reverend fathers; he is "divinely bent
to meditation," and must not be disturbed in his devotions by any
"worldly suits." They renew their entreaties to his messenger, and
implore the favour of an audience with his grace "in matter of great
moment."
Not till then does Gloucester show himself upon the balcony
between two bishops.
When, at the election of 1868, which turned upon the Irish Church
question, Disraeli, a very different man from Richard, was relying on
the co-operation of both English and Irish prelates, Punch depicted
him in fifteenth-century attire, standing on a balcony, prayer-book in
hand, with an indescribable expression of sly humility, while two
bishops, representing the English and the Irish Church, supported
him on either hand. The legend ran, in the words of the Lord Mayor:
"See where his grace stands 'tween two clergymen!"—whereupon
Buckingham remarks—
53. "Two props of virtue for a Christian prince,
To stay him from the fall of vanity;
And, see, a book of prayer in his hand,
True ornament to know a holy man."
The deputation is sternly repulsed, until Richard at last lets mercy
stand for justice, and recalling the envoys of the City, yields to their
insistence.
The third master-scene is that in Richard's tent on Bosworth Field (v.
3). It seems as though his hitherto immovable self-confidence had
been shaken; he feels himself weak; he will not sup. "Is my beaver
easier than it was? ... Fill me a bowl of wine.... Look that my staves
be sound and not too heavy." Again: "Give me a bowl of wine."
"I have not that alacrity of spirit,
Nor cheer of mind, that I was wont to have."
Then, in a vision, as he lies sleeping on his couch, with his armour
on and his sword-hilt grasped in his hand, he sees, one by one, the
spectres of all those he has done to death. He wakens in terror. His
conscience has a thousand tongues, and every tongue condemns
him as a perjurer and assassin:—
"I shall despair.—There is no creature loves me;
And if I die no soul shall pity me."
These are such pangs of conscience as would sometimes beset even
the strongest and most resolute in those days when faith and
superstition were still powerful, and when even one who scoffed at
religion and made a tool of it had no assurance in his heart of
hearts. There is in these words, too, a purely human sense of
loneliness and of craving for affection, which is valid for all time.
Most admirable is the way in which Richard summons up his
manhood and restores the courage of those around him. These are
the accents of one who will give despair no footing in his soul:—
"Conscience is but a word that cowards use,
Devis'd at first to keep the strong in awe;"
54. and there is in his harangue to the soldiers an irresistible roll of
fierce and spirit-stirring martial music; it is constructed like strophes
of the Marseillaise:—
"Remember whom you are to cope withal;—
A sort of vagabonds, rascals, runaways.
(Que veut cette horde d'esclaves?)
You having lands, and bless'd with beauteous
wives,
They would restrain the one, distain the other.
(Égorger vos fils, vos compagnes.)
Let's whip these stragglers o'er the seas again."
But there is a ferocity, a scorn, a popular eloquence in Richard's
words, in comparison with which the rhetoric of the Marseillaise
seems declamatory, even academic. His last speeches are nothing
less than superb:—
"Shall these enjoy our lands? lie with our wives?
Ravish our daughters?—[Drum afar off.] Hark; I hear
their
drum.
Fight, gentlemen of England! fight, bold yeomen!
Draw, archers, draw your arrows to the head!
Spur your proud horses hard, and ride in blood:
Amaze the welkin with your broken staves!
Enter a Messenger.
What says Lord Stanley? will he bring his power?
Mess. My lord, he doth deny to come.
K. Rich. Off with his son George's head!
Norfolk. My lord, the enemy is pass'd the marsh:
After the battle let George Stanley die.
K. Rich. A thousand hearts are great within my
bosom.
Advance our standards! set upon our foes!
55. Our ancient word of courage, fair Saint George,
Inspire us with the spleen of fiery dragons!
Upon them! Victory sits on our helms.
. . . . . . . . . . . . . . . . .
K. Rich. A horse! a horse! my kingdom for a horse!
Catesby. Withdraw, my lord; I'll help you to a horse.
K. Rich. Slave! I have set my life upon a cast,
And I will stand the hazard of the die.
I think there be six Richmonds in the field;
Five have I slain to-day, instead of him.—
A horse! a horse! my kingdom for a horse!"
In no other play of Shakespeare's, we may surely say, is the leading
character so absolutely predominant as here. He absorbs almost the
whole of the interest, and it is a triumph of Shakespeare's art that
he makes us, in spite of everything, follow him with sympathy. This
is partly because several of his victims are so worthless that their
fate seems well deserved. Anne's weakness deprives her of our
sympathy, and Richard's crime loses something of its horror when
we see how lightly it is forgiven by the one who ought to take it
most to heart. In spite of all his iniquities, he has wit and courage on
his side—a wit which sometimes rises to Mephistophelean humour, a
courage which does not fail him even in the moment of disaster, but
sheds a glory over his fall which is lacking to the triumph of his
coldly correct opponent. However false and hypocritical he may be
towards others, he is no hypocrite to himself. He is chemically free
from self-delusion, even applying to himself the most derogatory
terms; and this candour in the depths of his nature appeals to us. It
must be said for him, too, that threats and curses recoil from him
innocuous, that neither hatred nor violence nor superior force can
dash his courage. Strength of character is such a rare quality that it
arouses sympathy even in a criminal. If Richard's reign had lasted
longer, he would perhaps have figured in history as a ruler of the
type of Louis XI.: crafty, always wearing his religion on his sleeve,
but far-seeing and resolute. As a matter of fact, in history as in the
drama, his whole time was occupied in defending himself in the
56. position to which he had fought his way, like a bloodthirsty beast of
prey. His figure stands before us as his contemporaries have drawn
it: small and wiry, the right shoulder higher than the left, wearing his
rich brown hair long in order to conceal this malformation, biting his
under-lip, always restless, always with his hand on his dagger-hilt,
sliding it up and down in its sheath, without entirely drawing it.
Shakespeare has succeeded in throwing a halo of poetry around this
tiger in human shape.
The figures of the two boy princes, Edward's sons, stand in the
strongest contrast to Richard. The eldest child already shows
greatness of soul, a kingly spirit, with a deep feeling for the import
of historic achievement. The fact that Julius Cæsar built the Tower,
he says, even were it not registered, ought to live from age to age.
He is full of the thought that while Cæsar's "valour did enrich his
wit," yet it was his wit "that made his valour live," and he exclaims
with enthusiasm, "Death makes no conquest of this conqueror." The
younger brother is childishly witty, imaginative, full of boyish
mockery for his uncle's grimness, and eager to play with his dagger
and sword. In a very few touches Shakespeare has endowed these
young brothers with the most exquisite grace. The murderers "weep
like to children in their death's sad story":—
"Their lips were four red roses on a stalk,
And, in their summer beauty, kiss'd each other."
Finally, the whole tragedy of Richard's life and death is enveloped, as
it were, in the mourning of women, permeated with their
lamentations. In its internal structure, it bears no slight resemblance
to a Greek tragedy, being indeed the concluding portion of a
tetralogy.
Nowhere else does Shakespeare approach so nearly to the classicism
on the model of Seneca which had found some adherents in
England.
The whole tragedy springs from the curse which York, in the Third
Part of Henry VI. (i. 4), hurls at Margaret of Anjou. She has insulted
57. her captive enemy, and given him in mockery a napkin soaked in the
blood of his son, the young Rutland, stabbed to the heart by Clifford.
Therefore she loses her crown and her son, the Prince of Wales. Her
lover, Suffolk, she has already lost. Nothing remains to attach her to
life.
But now it is her turn to be revenged.
The poet has sought to incarnate in her the antique Nemesis, has
given her supernatural proportions and set her free from the
conditions of real life. Though exiled, she has returned unquestioned
to England, haunts the palace of Edward IV., and gives free vent to
her rage and hatred in his presence and that of his kinsfolk and his
courtiers. So, too, she wanders around under Richard's rule, simply
and solely to curse her enemies—and even Richard himself is seized
with a superstitious shudder at these anathemas.
Never again did Shakespeare so depart from the possible in order to
attain a scenic effect. And yet it is doubtful whether the effect is
really attained. In reading, it is true, these curses strike us with
extraordinary force; but on the stage, where she only disturbs and
retards the action, and takes no effective part in it, Margaret cannot
but prove wearisome.
Yet, though she herself remains inactive, her curses are effectual
enough. Death overtakes all those on whom they fall—the King and
his children, Rivers and Dorset, Lord Hastings and the rest.
She encounters the Duchess of York, the mother of Edward IV.,
Queen Elizabeth, his widow, and finally Anne, Richard's daringly-won
and quickly-repudiated wife. And all these women, like a Greek
chorus, give utterance in rhymed verse to imprecations and
lamentations of high lyric fervour. In two passages in particular (ii. 2
and iv. I) they chant positive choral odes in dialogue form. Take as
an example of the lyric tone of the diction these lines (iv. I):—.
"Duchess of York [To Dorset.] Go thou to Richmond, and good
fortune guide thee!—
58. [To Anne.] Go thou to Richard, and good angels tend thee!
[To Q. Elizabeth.] Go thou to sanctuary, and good thoughts
possess thee!—
I to my grave, where peace and rest lie with me!
Eighty odd years of sorrow have I seen,
And each hour's joy wrack'd with a week of teen."
Such is this work of Shakespeare's youth, firm, massive, and
masterful throughout, even though of very unequal merit. Everything
is here worked out upon the surface; the characters themselves tell
us what sort of people they are, and proclaim themselves evil or
good, as the case may be. They are all transparent, all self-conscious
to excess. They expound themselves in soliloquies, and each of them
is judged in a sort of choral ode. The time is yet to come when
Shakespeare no longer dreams of making his characters formally
hand over to the spectators the key to their mystery—when, on the
contrary, with his sense of the secrets and inward contradictions of
the spiritual life, he sedulously hides that key in the depths of
personality.
XIX
SHAKESPEARE LOSES HIS SON—TRACES OF HIS GRIEF IN
KING JOHN—THE OLD PLAY OF THE SAME NAME—
DISPLACEMENT OF ITS CENTRE OF GRAVITY—ELIMINATION
OF RELIGIOUS POLEMICS—RETENTION OF THE NATIONAL
BASIS—PATRIOTIC SPIRIT—SHAKESPEARE KNOWS
NOTHING OF THE DISTINCTION BETWEEN NORMANS AND
ANGLO-SAXONS, AND IGNORES THE MAGNA CHARTA
In the Parish Register of Stratford-on-Avon for 1596, under the
heading of burials, we find this entry, in a clear and elegant
59. handwriting:—
"August 11, Hamnet filius William Shakespeare."
Shakespeare's only son was born on the 2nd of February 1585; he
was thus only eleven and a half when he died.
We cannot doubt that this loss was a grievous one to a man of
Shakespeare's deep feeling; doubly grievous, it would seem,
because it was his constant ambition to restore the fallen fortunes of
his family, and he was now left without an heir to his name.
Traces of what his heart must have suffered appear in the work he
now undertakes, King John, which seems to date from 1596-97.
One of the main themes of this play is the relation between John
Lackland, who has usurped the English crown, and the rightful heir,
Arthur, son of John's elder brother, in reality a boy of about fourteen
at the date of the action, but whom Shakespeare, for the sake of
poetic effect, and influenced, perhaps, by his private preoccupations
of the moment, has made considerably younger, and consequently
more childlike and touching.
The King has got Arthur into his power. The most famous scene in
the play is that (iv. I) in which Hubert de Burgh, the King's
chamberlain, who has received orders to sear out the eyes of the
little captive, enters Arthur's prison with the irons, and accompanied
by the two servants who are to bind the child to a chair and hold
him fast while the atrocity is being committed. The little prince, who
has no mistrust of Hubert, but only a general dread of his uncle's
malice, as yet divines no danger, and is full of sympathy and childlike
tenderness. The passage is one of extraordinary grace:—
"Arthur You are sad.
Hubert. Indeed, I have been merrier.
Arth. Mercy on me
Methinks, nobody should be sad but I:
. . . . . . . .
I would to Heaven,
I were your son, so you would love me, Hubert.
60. Hub. [Aside.] If I talk to him, with his innocent
prate
He will awake my mercy, which lies dead:
Therefore I will be sudden, and despatch.
Arth. Are you sick, Hubert? you look pale to-day.
In sooth, I would you were a little sick,
That I might sit all night, and watch with you:
I warrant, I love you more than you do me."
Hubert gives him the royal mandate to read:—
"Hubert. Can you not read it? is it not fair writ?
Arthur. Too fairly, Hubert, for so foul effect.
Must you with hot irons burn out both mine eyes?
Hub. Young boy, I must.
Arth . And will you?
Hub . And I
will.
Arth. Have you the heart? When your head did but
ache,
I knit my handkerchief about your brows,
(The best I had, a princess wrought it me,)
And I did never ask it you again;
And with my hand at midnight held your head."
Hubert summons the executioners, and the child promises to sit still
and offer no resistance if only he will send these "bloody men" away.
One of the servants as he goes out speaks a word of pity, and Arthur
is in despair at having "chid away his friend." In heart-breaking
accents he begs mercy of Hubert until the iron has grown cold, and
Hubert has not the heart to heat it afresh.
Arthur's entreaties to the rugged Hubert to spare his eyes, must
have represented in Shakespeare's thought the prayers of his little
Hamnet to be suffered still to see the light of day, or rather
Shakespeare's own appeal to Death to spare the child—prayers and
appeals which were all in vain.
61. It is, however, in the lamentations of Arthur's mother, Constance,
when the child is carried away to prison (iii. 4), that we most clearly
recognise the accents of Shakespeare's sorrow:—
"Pandulph. Lady, you utter madness, and not
sorrow.
Constance. I am not mad: this hair I tear is mine.
If I were mad, I should forget my son,
Or madly think, a babe of clouts were he.
I am not mad: too well, too well I feel
The different plague of each calamity."
She pours forth her anguish at the thought of his sufferings in
prison:—
"Now will canker sorrow eat my bud,
And chase the native beauty from his cheek,
And he will look as hollow as a ghost,
As dim and meagre as an ague's fit,
And so he'll die.
. . . . . . . . .
Pandulph. You hold too heinous a respect of grief.
Constance. He talks to me, that never had a son.
K. Philip. You are as fond of grief as of your child."
Const. Grief fills the room up of my absent child,
Lies in his bed, walks up and down with me,
Puts on his pretty looks, repeats his words,
Remembers me of all his gracious parts,
Stuffs out his vacant garments with his form."
It seems as though Shakespeare's great heart had found an outlet
for its own sorrows in transfusing them into the heart of Constance.
Shakespeare used as the basis of his King John an old play on the
same subject published in 1591.[1] This play is quite artless and
spiritless, but contains the whole action, outlines all the characters,
and suggests almost all the principal scenes. The poet did not
require to trouble himself with the invention of external traits. He
62. could concentrate his whole effort upon vitalising, spiritualising, and
deepening everything. Thus it happens that this play, though never
one of his most popular (it seems to have been but seldom
performed during his lifetime, and remained in manuscript until the
appearance of the First Folio), nevertheless contains some of his
finest character-studies and a multitude of pregnant, imaginative,
and exquisitely worded speeches.
The old play was a mere Protestant tendency-drama directed against
Catholic aggression, and full of the crude hatred and coarse ridicule
of monks and nuns characteristic of the Reformation period.
Shakespeare, with his usual tact, has suppressed the religious
element, and retained only the national and political attack upon
Roman Catholicism, so that the play had no slight actuality for the
Elizabethan public. But he has also displaced the centre of gravity of
the old play. Everything in Shakespeare turns upon John's defective
right to the throne: therein lies the motive for the atrocity he plans,
which leads (although it is not carried out as he intended) to the
barons' desertion of his cause.
Despite its great dramatic advantages over Richard II., the play
surfers from the same radical weakness, and in an even greater
degree: the figure of the King is too unsympathetic to serve as the
centre-point of a drama. His despicable infirmity of purpose, which
makes him kneel to receive his crown at the hands of the same
Papal legate whom he has shortly before defied in blusterous terms;
his infamous scheme to assassinate an innocent child, and his
repentance when he sees that its supposed execution has alienated
the chief supporters of his throne—all this hideous baseness,
unredeemed by any higher characteristics, leads the spectator rather
to attach his interest to the subordinate characters, and thus the
action is frittered away before his eyes. It lacks unity, because the
King is powerless to hold it together.
He himself is depicted for all time in the masterly scene (iii. 3) where
he seeks, without putting his thought into plain words, to make
Hubert understand that he would fain have Arthur murdered:—
63. "Or if that thou couldst see me without eyes,
Hear me without thine ears, and make reply
Without a tongue, using conceit alone,
Without eyes, ears, and harmful sound of words:
Then, in despite of brooded-watchful day,—
I would into thy bosom pour my thoughts.
But, ah! I will not:—yet I love thee well."
Hubert protests his fidelity and devotion. Even if he were to die for
the deed, he would execute it for the King's sake. Then John's
manner becomes hearty, almost affectionate. "Good Hubert,
Hubert!" he says caressingly. He points to Arthur, bidding Hubert
"throw his eye on yon young boy;" and then follows this masterly
dialogue:—
"I'll tell thee what, my friend,
He is a very serpent in my way;
And wheresoe'er this foot of mine doth tread,
He lies before me. Dost thou understand me?
Thou art his keeper.
Hub. And I'll keep him so,
That he shall not offend your majesty.
K. John. Death.
Hub. My Lord.
K. John. A grave.
Hub. He shall not live.
K. John.
Enough
I could be merry now. Hubert, I love thee;
Well, I'll not say what I intend for thee:
Remember.—Madam, fare you well:
I'll send those powers o'er to your majesty.
Elinor. My blessing go with thee!"
The character that bears the weight of the piece, as an acting play,
is the illegitimate son of Richard Cœur-de-Lion, Philip Faulconbridge.
He is John Bull himself in the guise of a mediæval knight, equipped
64. with great strength and a racy English humour, not the wit of a
Mercutio, a gay Italianising cavalier, but the irrepressible ebullitions
of rude health and blunt gaiety befitting an English Hercules. The
scene in the first act, in which he appears along with his brother,
who seeks to deprive him of his inheritance as a Faulconbridge on
the ground of his alleged illegitimacy, and the subsequent scene with
his mother, from whom he tries to wring the secret of his paternity,
both appear in the old play; but in it everything that the Bastard
says is in grim earnest—the embroidery of wit belongs to
Shakespeare alone. It is he who has placed in Faulconbridge's mouth
such sayings as this:—
"Madam, I was not old Sir Robert's son:
Sir Robert might have eat his part in me
Upon Good Friday, and ne'er broke his fast."
And it is quite in Shakespeare's spirit when the son, after her
confession, thus consoles his mother:—
"Madam, I would not wish a better father.
Some sins do bear their privilege on earth,
And so doth yours."
In later years, at a time when his outlook upon life was darkened,
Shakespeare accounted for the villainy of Edmund, in King Lear and
for his aloofness from anything like normal humanity, on the ground
of his irregular birth; in the Bastard of this play, on the contrary, his
aim was to present a picture of all that health, vigour, and full-
blooded vitality which popular belief attributes to a "Love-child."
The antithesis to this national hero is Limoges, Archduke of Austria,
in whom Shakespeare, following the old play, has mixed up two
entirely distinct personalities: Vidomar, Viscount of Limoges, at the
siege of one of whose castles Richard Cœur-de-Lion was killed, in
1199, and Leopold V., Archduke of Austria, who had kept Cœur-de-
Lion in prison. Though the latter, in fact, died five years before
Richard, we here find him figuring as the dastardly murderer of the
heroic monarch. In memory of this deed he wears a lion's skin on his
65. shoulders, and thus brings down upon himself the indignant scorn of
Constance and Faulconbridge's taunting insults:—
"Constance. Thou wear a lion's hide! doff it for
shame,
And hang a calf's-skin on those recreant limbs.
Austria. O, that a man should speak those words to
me!
Bastard. And hang a calf's-skin on those recreant
limbs.
Aust. Thou dar'st not say so, villain, for thy life.
Bast. And hang a calf's-skin on those recreant
limbs."
Every time the Archduke tries to get in a word of warning or
counsel, Faulconbridge silences him with this coarse sarcasm.
Faulconbridge is at first full of youthful insolence, the true mediæval
nobleman, who despises the burgess class simply as such. When the
inhabitants of Angiers refuse to open their gates either to King John
or to King Philip of France, who has espoused the cause of Arthur,
the Bastard is so indignant at this peace-loving circumspection that
he urges the kings to join their forces against the unlucky town, and
cry truce to their feud until the ramparts are levelled to the earth.
But in the course of the action he ripens more and more, and
displays ever greater and more estimable qualities—humanity, right-
mindedness, and a fidelity to the King which does not interfere with
generous freedom of speech towards him.
His method of expression is always highly imaginative, more so than
that of the other male characters in the play. Even the most abstract
ideas he personifies. Thus he talks (iii. I) of—
"Old Time, the clock-setter, that bald sexton Time."
In the old play whole scenes are devoted to his execution of the task
here allotted him of visiting the monasteries of England and
lightening the abbots' bursting money-bags. Shakespeare has
suppressed these ebullitions of an anti-Catholic fervour, which he did
66. not share. On the other hand, he has endowed Faulconbridge with
genuine moral superiority. At first he is only a cheery, fresh-natured,
robust personality, who tramples upon all social conventions,
phrases, and affectations; and indeed he preserves to the last
something of that contempt for "cockered silken wantons" which
Shakespeare afterwards elaborates so magnificently in Henry Percy.
But there is real greatness in his attitude when, at the close of the
play, he addresses the vacillating John in this manly strain (v. I):—
"Let not the world see fear, and sad distrust,
Govern the motion of a kingly eye:
Be stirring as the time; be fire with fire;
Threaten the threatener, and outface the brow
Of bragging horror: so shall inferior eyes,
That borrow their behaviours from the great,
Grow great by your example, and put on
The dauntless spirit of resolution."
Faulconbridge is in this play the spokesman of the patriotic spirit. But
we realise how strong was Shakespeare's determination to make this
string sound at all hazards, when we find that the first eulogy of
England is placed in the mouth of England's enemy, Limoges, the
slayer of Cœur-de-Lion, who speaks (ii. I) of—
"that pale, that white'-fac'd shore,
Whose foot spurns back the ocean's roaring tides,
And coops from other lands her islanders,
... that England, hedg'd in with the main,
That water-walled bulwark, still secure
And confident from foreign purposes."
How slight is the difference between the eulogistic style of the two
mortal enemies, when Faulconbridge, who has in the meantime
killed Limoges, ends the play with a speech, which is, however, only
slightly adapted from the older text:—
"This England never did, nor never shall,
Lie at the proud foot of a conqueror.
67. . . . . . . . .
Come the three corners of the world in arms,
And we shall shock them. Naught shall make us rue,
If England to itself do rest but true."
Next to Faulconbridge, Constance is the character who bears the
weight of the play; and its weakness arises in great part from the
fact that Shakespeare has killed her at the end of the third act. So
lightly is her death treated, that it is merely announced in passing by
the mouth of a messenger. She does not appear at all after her son
Arthur is put out of the way, possibly because Shakespeare feared to
lengthen the list of sorrowing and vengeful mothers already
presented in his earlier histories.
He has treated this figure with a marked predilection, such as he
usually manifests for those characters which, in one way or another,
forcibly oppose every compromise with lax worldliness and
euphemistic conventionality. He has not only endowed her with the
most passionate and enthusiastic motherly love, but with a wealth of
feeling and of imagination which gives her words a certain poetic
magnificence. She wishes that "her tongue were in the thunder's
mouth, Then with a passion would she shake the world" (iii. 4). She
is sublime in her grief for the loss of her son:—
"I will instruct my sorrows to be proud,
For grief is proud, and makes his owner stoop.
To me, and to the state of my great grief,
Let kings assemble;
. . . . . .
Here I and sorrows sit;
Here is my throne, bid kings come bow to it.
Seats herself on the ground."
Yet Shakespeare is already preparing us, in the overstrained violence
of these expressions, for her madness and death.
The third figure which fascinates the reader of King John is that of
Arthur. All the scenes in which the child appears are contained in the
68. old play of the same name, and, among the rest, the first scene of
the second act, which seems to dispose of Fleay's conjecture that
the first two hundred lines of the act were hastily inserted after
Shakespeare had lost his son. Nevertheless almost all that is
gracious and touching in the figure is due to the great reviser. The
old text is at its best in the scene where Arthur meets his death by
jumping from the walls of the castle. Shakespeare has here confined
himself for the most part to free curtailment; in the old King John,
his fatal fall does not prevent Arthur from pouring forth copious
lamentations to his absent mother and prayers to "sweete Iesu."
Shakespeare gives him only two lines to speak after his fall.
In this play, as in almost all the works of Shakespeare's younger
years, the reader is perpetually amazed to find the finest poetical
and rhetorical passages side by side with the most intolerable
euphuistic affectations. And we cannot allege the excuse that these
are legacies from the older play. On the contrary, there is nothing of
the kind to be found in it; they are added by Shakespeare, evidently
with the express purpose of displaying delicacy and profundity of
thought. In the scenes before the walls of Angiers, he has on the
whole kept close to the old drama, and has even followed faithfully
the sense of all the more important speeches. For example, it is a
citizen on the ramparts, who, in the old play, suggests the marriage
between Blanch and the Dauphin; Shakespeare merely re-writes his
speech, introducing into it these beautiful lines (ii. 2):—
"If lusty love should go in quest of beauty,
Where should he find it fairer than in Blanch?
If zealous love should go in search of virtue,
Where should he find it purer than in Blanch?
If love ambitious sought a match of birth,
Whose veins bound richer blood than Lady Blanch?"
The surprising thing is that the same hand which has just written
these verses should forthwith lose itself in a tasteless tangle of
affectations like this:—
69. "Such as she is, in beauty, virtue, birth,
Is the young Dauphin every way complete:
If not complete of, say, he is not she;
And she again wants nothing, to name want,
If want it be not, that she is not he:"
and this profound thought is further spun out with a profusion of
images. Can we wonder that Voltaire and the French critics of the
eighteenth century were offended by a style like this, even to the
point of letting it blind them to the wealth of genius elsewhere
manifested?
Even the touching scene between Arthur and Hubert is disfigured by
false cleverness of this sort. The little boy, kneeling to the man who
threatens to sear out his eyes, introduces, in the midst of the most
moving appeals, such far-fetched and contorted phrases as this (iv.
I):—
"The iron of itself, though heat red-hot,
Approaching near these eyes, would drink my tears,
And quench this fiery indignation
Even in the matter of mine innocence;
Nay, after that, consume away in rust,
But for containing fire to harm mine eye."
And again, when Hubert proposes to reheat the iron:—
"An if you do, you will but make it blush,
And glow with shame of your proceedings, Hubert."
The taste of the age must indeed have pressed strongly upon
Shakespeare's spirit to prevent him from feeling the impossibility of
these quibbles upon the lips of a child imploring in deadly fear that
his eyes may be spared to him.
As regards their ethical point of view, there is no essential difference
between the old play and Shakespeare's. The King's defeat and
painful death is in both a punishment for his wrongdoing. There has
only been, as already mentioned, a certain displacement of the
centre of gravity. In the old play, the dying John stammers out an
70. explicit confession that from the moment he surrendered to the
Roman priest he has had no more happiness on earth; for the Pope's
curse is a blessing, and his blessing a curse. In Shakespeare the
emphasis is laid, not upon the King's weakness in the religio-political
struggle, but upon the wrong to Arthur. Faulconbridge gives
utterance to the fundamental idea of the play when he says (iv. 3):—
"From forth this morsel of dead royalty,
The life, the right, and truth of all this realm
Is fled to heaven."
Shakespeare's political standpoint is precisely that of the earlier
writer, and indeed, we may add, of his whole age.
The most important contrasts and events of the period he seeks to
represent do not exist for him. He naïvely accepts the first kings of
the House of Plantagenet, and the Norman princes in general, as
English national heroes, and has evidently no suspicion of the deep
gulf that separated the Normans from the Anglo-Saxons down to this
very reign, when the two hostile races, equally oppressed by the
King's tyranny, began to fuse into one people. What would
Shakespeare have thought had he known that Richard Cœur-de-
Lion's favourite formula of denial was "Do you take me for an
Englishman?" while his pet oath, and that of his Norman followers,
was "May I become an Englishman if—," &c.?
Nor does a single phrase, a single syllable, in the whole play, refer to
the event which, for all after-times, is inseparably associated with
the memory of King John—the signing of the Magna Charta. The
reason of this is evidently, in the first place, that Shakespeare kept
close to the earlier drama, and, in the second place, that he did not
attribute to the event the importance it really possessed, did not
understand that the Magna Charta laid the foundation of popular
liberty, by calling into existence a middle class which supported even
the House of Tudor in its struggle with an overweening oligarchy. But
the chief reason why the Magna Charta is not mentioned was, no
doubt, that Elizabeth did not care to be reminded of it. She was not
fond of any limitations of her royal prerogative, and did not care to
71. recall the defeats suffered by her predecessors in their struggles
with warlike and independent vassals. And the nation was willing
enough to humour her in this respect. People felt that they had to
thank her government for a great national revival, and therefore
showed no eagerness either to vindicate popular rights against her,
or to see them vindicated in stage-history. It was not until long after,
under the Stuarts, that the English people began to cultivate its
constitution. The chronicle-writers of the period touch very lightly
upon the barons' victory over King John in the struggle for the Great
Charter; and Shakespeare thus followed at once his own personal
bias with regard to history, and the current of his age.
72. [1] The full title runs thus: "The Troublesome Raigne of John, King of England,
with the discouerie of King Richard Cordelions Base sonne (vulgarly named The
Bastard Fawconbridge): also the death of King John at Swinstead Abbey. As it was
(sundry times) publikely acted by the Queenes Maiesties Players, in the honorable
Citie of London."
XX
"THE TAMING OF THE SHREW" AND "THE MERCHANT OF
VENICE"—SHAKESPEARE'S PREOCCUPATION WITH
THOUGHTS OF PROPERTY AND GAIN—HIS GROWING
PROSPERITY—HIS ADMISSION TO THE RANKS OF THE
"GENTRY"—HIS PURCHASE OF HOUSES AND LAND—MONEY
TRANSACTIONS AND LAWSUITS
The first plays in which we seem to find traces of Italian travel are
The Taming of the Shrew and The Merchant of Venice, the former
written at latest in 1596, the latter almost certainly in that or the
following year.
Enough has already been said of The Taming of the Shrew. It is only
a free and spirited reconstruction of an old piece of scenic
architecture, which Shakespeare demolished in order to erect from
its materials a spacious and airy hall. The old play itself had been
highly popular on the stage; it took new life under Shakespeare's
hands. His play is not much more than a farce, but it possesses
movement and fire, and the leading male character, the somewhat
coarsely masculine Petruchio, stands in amusing and typical contrast
to the spoilt, headstrong, and passionate little woman whom he
masters.
The Merchant of Venice, Shakespeare's first important comedy, is a
piece of work of a very different order, and is elaborated to a very
73. different degree. There is far more of his own inmost nature in it
than in the light and facile farce.
No doubt he found in Marlowe's Jew of Malta the first, purely
literary, impulse towards The Merchant of Venice. In Marlowe's play
the curtain rises upon the chief character, Barabas, sitting in his
counting-house, with piles of gold before him, and revelling in the
thought of the treasures which it takes a soliloquy of nearly fifty
lines to enumerate—pearls like pebble-stones, opals, sapphires,
amethysts, jacinths, topazes, grass-green emeralds, beauteous
rubies and sparkling diamonds. At the beginning of the play, he is
possessed of all the riches wherewith the Genie of the Lamp
endowed Aladdin, which have at one time or another sparkled in the
dreams of all poor poets.
Barabas is a Jew and usurer, like Shylock. Like Shylock, he has a
daughter who is in love with a poor Christian; and, like him, he
thirsts for revenge. But he is a monster, not a man. When he has
been misused by the Christians, and robbed of his whole fortune, he
becomes a criminal fit only for a fairy-tale or for a madhouse: he
uses his own daughter as an instrument for his revenge, and then
poisons her along with all the nuns in whose cloister she has taken
refuge. Shakespeare was attracted by the idea of making a real man
and a real Jew out of this intolerable demon in a Jew's skin.
But this slight impulse would scarcely have set Shakespeare's genius
in motion had it found him engrossed in thoughts and images of an
incongruous nature. It took effect upon his mind because it was at
that moment preoccupied with the ideas of acquisition, property,
money-making, wealth. He did not, like the Jew, who was in all
countries legally incapable of acquiring real estate, dream of gold
and jewels; but, like the genuine country-born Englishman he was,
he longed for land and houses, meadows and gardens, money that
yielded sound yearly interest, and, finally, a corresponding
advancement in rank and position.
We have seen with what indifference he treated his plays, how little
he thought of winning fame by their publication. All the editions of
74. them which appeared in his lifetime were issued without his co-
operation, and no doubt against his will, since the sale of the books
did not bring him in a farthing, but, on the contrary, diminished his
profits by diminishing the attendance at the theatre on which his
livelihood depended. Furthermore, when we see in his Sonnets how
discontented he was with his position as an actor, and how
humiliated he felt at the contempt in which the stage was held, we
cannot doubt that the calling into which he had drifted in his needy
youth was in his eyes simply and solely a means of making money. It
is true that actors like himself and Burbage were, in certain circles,
welcomed and respected as men who rose above their calling; but
they were admitted on sufferance, they had not full rights of
citizenship, they were not "gentlemen." There is extant a copy of
verses by John Davies of Hereford, beginning, "Players, I love yee,
and your Qualitie" with a marginal note citing as examples "W. S., R.
B." [William Shakespeare, Richard Burbage]; but they are clearly
looked upon as exceptions:—
"And though the stage doth staine pure gentle bloud,
Yet generous yee are in minde and moode".
The calling of an actor, however, was a lucrative one. Most of the
leading players became well-to-do, and it seems clear that this was
one of the reasons why they were evilly regarded. In The Return
from Parnassus (1606), Kemp assures two Cambridge students who
apply to him and Burbage for instruction in acting, that there is no
better calling in the world, from a financial point of view, than that
of the player. In a pamphlet of the same year, Ratsey's Ghost, the
executed thief, with a satirical allusion to Shakespeare, advises a
strolling player to buy property in the country when he is tired of
play-acting, and by that means attain honour and dignity. In an
epigram entitled Theatrum Licentia (in Laquei Ridiculosi, 1616), we
read of the actor's calling:—
"For here's the spring (saith he) whence pleasures flow
And brings them damnable excessive gains."
75. The primary object of Shakespeare's aspirations was neither renown
as a poet nor popularity as an actor, but worldly prosperity, and
prosperity regarded specially as a means of social advancement. He
had taken greatly to heart his father's decline in property and civic
esteem; from youth upwards he had been passionately bent on
restoring the sunken name and fame of his family. He had now, at
the age of only thirty-two, amassed a small capital, which he began
to invest in the most advantageous way for the end he had in view—
that of elevating himself above his calling.
His father had been afraid to cross the street lest he should be
arrested for debt. He himself, as a youth, had been whipped and
consigned to the lock-up at the command of the lord of the manor.
The little town which had witnessed this disgrace should also witness
the rehabilitation. The townspeople, who had heard of his equivocal
fame as an actor and playwright, should see him in the character of
a respected householder and landowner. At Stratford and elsewhere,
those who had classed him with the proletariat should recognise in
him a gentleman. According to a tradition which Rowe reports on the
authority of Sir William Davenant, Lord Southampton is said to have
laid the foundation of Shakespeare's prosperity by a gift of £1.000.
Though Bacon received more than this from Essex, the magnitude of
the sum discredits the tradition—it is equivalent to something like
£5000 in modern money. No doubt the young Earl gave the poet a
present in acknowledgment of the dedication of his two poems; for
the poets of that time did not live on royalties, but on their
dedications. But as the ordinary acknowledgment of a dedication
was only £5, a gift of even £50 would have been reckoned princely.
What is practically certain is, that Shakespeare was early in a
position to become a shareholder in the theatre; and he evidently
had a special talent for putting the money he earned to profitable
use. His firm determination to work his way up in the world,
combined with the Englishman's inborn practicality, made him an
excellent man of business; and he soon develops such a decided
talent for finance as only two other great national writers, probably,
have ever possessed—to wit, Holberg and Voltaire.
76. It is from the year 1596 onwards that we find evidences of his
growing prosperity. In this year his father, no doubt prompted and
supplied with means by Shakespeare himself, makes application to
the Heralds' College for a coat-of-arms, the sketch of which is
preserved, dated October 1596. The conferring of a coat-of-arms
implied formal admittance into the ranks of "the gentry." It was
necessary before either father or son could append the word
"gentleman" (armiger) to his name, as we find Shakespeare doing in
legal documents after this date, and in his will. But Shakespeare
himself was not in a position to apply for a coat-of-arms. That was
out of the question—a player was far too mean a person to come
within the cognisance of heraldry. He therefore adopted the shrewd
device of furnishing his father with means for making the application
on his own behalf.
According to the ideas and regulations of the time, indeed, not even
Shakespeare senior had any real right to a coat-of-arms. But the
Garter-King-at-Arms for the time being, Sir William Dethick, was an
exceedingly compliant personage, probably not inaccessible to
pecuniary arguments. He was sharply criticised in his own day, and
indeed at last superseded, on account of the facility with which he
provided applicants with armorial bearings, and we possess his
defence in this very matter of the Shakespeare coat-of-arms. All
sorts of small falsehoods were alleged; for instance, that John
Shakespeare had, twenty years before, had "his auncient cote of
arms assigned to him," and that he was then "Her Majestie's officer
and baylefe," whereas his office had in fact been merely municipal.
Nevertheless, there must have been some hitch in the negotiations,
for in 1597 John Shakespeare is still described as yeoman, and not
until 1599 did the definite assignment of the coat-of-arms take
place, along with the permission (of which the son, however, did not
avail himself) to impale the Shakespeare arms with those of the
Arden family. The coat-of-arms is thus described:—"Gould on a bend
sable a speare of the first, the poynt steeled, proper, and for creast
or cognizance, a faulcon, his wings displayed, argent, standing on a
wreathe of his coullors, supporting a speare gould steled as
77. Welcome to our website – the ideal destination for book lovers and
knowledge seekers. With a mission to inspire endlessly, we offer a
vast collection of books, ranging from classic literary works to
specialized publications, self-development books, and children's
literature. Each book is a new journey of discovery, expanding
knowledge and enriching the soul of the reade
Our website is not just a platform for buying books, but a bridge
connecting readers to the timeless values of culture and wisdom. With
an elegant, user-friendly interface and an intelligent search system,
we are committed to providing a quick and convenient shopping
experience. Additionally, our special promotions and home delivery
services ensure that you save time and fully enjoy the joy of reading.
Let us accompany you on the journey of exploring knowledge and
personal growth!
ebookultra.com