DEV Community

Cover image for Modern Full-Stack Serverless, Part I
AWS Community Builders

Modern Full-Stack Serverless, Part I

Salah Elhossiny
ML engineer || AWS Certified MLS || AWS Community Builders member || Fullstack developer
Updated on ・9 min read

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 mindset 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,” .

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 Service) offerings. Put simply, serverless computing = FaaS + BaaS.

Backend as a service (BaaS) typically refers to managed services like databases (Firestore, 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:


Serverless architectures typically allow you to shift more of your operational responsibilities 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, maintaining, 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 delivering business value.


Managed services usually assume responsibility for providing a defined set of features.

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


Low cost (pay as you go)

Developer velocity

Less code

Different Implementations of Serverless


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 supported 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 (serverless.yml), CLI, and function code to provide a nice experience for people wanting to deploy serverless functions and other AWS services to the cloud from a local environment. Getting up and running with the Serverless Framework can present a somewhat 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 (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 disadvantage 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 serverless applications to AWS.


The Amplify Framework is a combination of four things: CLI, client library, toolchain, 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 alsoGraphQL APIs, machine learning (ML), storage, analytics, push notifications, 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.


The CLI allows you to create, configure, and deploy cloud services from the command 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 generating 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.

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.
You can develop serverless apps using those following frameworks

Amplify CLI
Amplify CLient
AWS AppSync (managed API layer that uses GraphQL)

Installing and Configuring the Amplify CLI

To get started, you first need to install and configure the Amplify CLI:

 ~ npm npm install -g @aws-amplify/cli 
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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.

Create a project

~ npx create-react-app react-amplify-project 
~ cd react amplify-project 
Enter fullscreen mode Exit fullscreen mode

Next, you can create an Amplify project. To do so, you’ll run the init command:

~ amplify init
Enter fullscreen mode Exit fullscreen mode

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.

  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 initialization 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.

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.

#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 provisioned in the cloud and what is currently in your local backend directory (which reflects your local changes).

Creating and Deploying Your First Service

To create a new service, you can use the add command from Amplify:

~ amplify add auth 
Enter fullscreen mode Exit fullscreen mode

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 authentication 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 
Enter fullscreen mode Exit fullscreen mode
  1. Are you sure you want to continue? Choose Y.

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 application. 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';
Enter fullscreen mode Exit fullscreen mode

Now, the app has been configured and you can begin interacting with the authentication service. Next, open src/App.js and update the file with the following code:

 import React from 'react'
  import { withAuthenticator, AmplifySignOut } from '@aws-
  function App() {
  return (
  <h1>Hello from AWS Amplify</h1>
  <AmplifySignOut />

  export default withAuthenticator(App); 
Enter fullscreen mode Exit fullscreen mode

Now you can launch the app using:

~ npm start 
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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 
Enter fullscreen mode Exit fullscreen mode


  1. Book: Full Stack Serverless: Modern Application Development with React, AWS, and GraphQL (By Nader Dabit)


  3. Part II:

Discussion (2)

prasanjit_singh profile image
Prasanjit Singh


salah856 profile image
Salah Elhossiny Author

Thanks for support