28,14 €
Learn to design and deploy fully functioning microservices for your applications from scratch using Swift, Docker, and AWS
Key Features
Book Description
The capabilities of the Swift programming language are extended to server-side development using popular frameworks such as Vapor. This enables Swift programmers to implement the microservices approach to design scalable and easy-to-maintain architecture for iOS, macOS, iPadOS, and watchOS applications.
This book is a complete guide to building microservices for iOS applications. You'll start by examining Swift and Vapor as backend technologies and compare them to their alternatives. The book then covers the concept of microservices to help you get started with developing your first microservice. Throughout this book, you'll work on a case study of writing an e-commerce backend as a microservice application. You'll understand each microservice as it is broken down into details and written out as code throughout the book. You'll also become familiar with various aspects of server-side development such as scalability, database options, and information flow for microservices that are unwrapped in the process. As you advance, you'll get to grips with microservices testing and see how it is different from testing a monolith application. Along the way, you'll explore tools such as Docker, Postman, and Amazon Web Services.
By the end of the book, you'll be able to build a ready-to-deploy application that can be used as a base for future applications.
What you will learn
Who this book is for
The book is for iOS, iPadOS, and macOS developers and Swift programmers who want to understand how Swift can be used for building microservices. The book assumes familiarity with Swift programming and the fundamentals of the web, including how APIs work.
Das E-Book können Sie in Legimi-Apps oder einer beliebigen App lesen, die das folgende Format unterstützen:
Seitenzahl: 402
Veröffentlichungsjahr: 2020
Copyright © 2020 Packt Publishing
All rights reserved. No part of this book may be reproduced, stored in a retrieval system, or transmitted in any form or by any means, without the prior written permission of the publisher, except in the case of brief quotations embedded in critical articles or reviews.
Every effort has been made in the preparation of this book to ensure the accuracy of the information presented. However, the information contained in this book is sold without warranty, either express or implied. Neither the author, nor Packt Publishing or its dealers and distributors, will be held liable for any damages caused or alleged to have been caused directly or indirectly by this book.
Packt Publishing has endeavored to provide trademark information about all of the companies and products mentioned in this book by the appropriate use of capitals. However, Packt Publishing cannot guarantee the accuracy of this information.
Commissioning Editor:Kunal ChaudhariAcquisition Editor:Heramb BhavsarContent Development Editor:Aamir AhmedSenior Editor: Hayden EdwardsTechnical Editor: Sachin SunilkumarCopy Editor: Safis EditingProject Coordinator:Kinjal BariProofreader: Safis EditingIndexer:Tejal Daruwale SoniProduction Designer:Jyoti Chauhan
First published: February 2020
Production reference: 1280220
Published by Packt Publishing Ltd. Livery Place 35 Livery Street Birmingham B3 2PB, UK.
ISBN 978-1-78953-088-9
www.packt.com
Packt.com
Subscribe to our online digital library for full access to over 7,000 books and videos, as well as industry leading tools to help you plan your personal development and advance your career. For more information, please visit our website.
Spend less time learning and more time coding with practical eBooks and Videos from over 4,000 industry professionals
Improve your learning with Skill Plans built especially for you
Get a free eBook or video every month
Fully searchable for easy access to vital information
Copy and paste, print, and bookmark content
Did you know that Packt offers eBook versions of every book published, with PDF and ePub files available? You can upgrade to the eBook version at www.packt.com and as a print book customer, you are entitled to a discount on the eBook copy. Get in touch with us at [email protected] for more details.
At www.packt.com, you can also read a collection of free technical articles, sign up for a range of free newsletters, and receive exclusive discounts and offers on Packt books and eBooks.
I had the pleasure of meeting Ralph in person at the first Server-Side Swift conference in Berlin in 2018. We met again at the next conference in Copenhagen. Ralph is quite a friendly person and we spent a lot of time getting to know each other and sharing ideas.
Ralph's experience studying and practicing business spanning over a decade have given him unique insights into the problems facing web developers today. In addition to his business acumen, he also has a deep understanding of programming. A man after my own heart, he's always eager to try new things and share his knowledge with others.
A few months before we met in person, Ralph's company, Skelpo, became Vapor's second major sponsor. This early support for the framework has proven to be invaluable. Beyond mere sponsorship, Ralph has been actively involved with the development of the framework. He is quick to adopt changes and give feedback. This feedback is critical to Vapor's success and shows his mastery of the framework.
What's more, Ralph is now well-known throughout the Vapor community. He has created many opportunities for contributors to work on related projects and give back to the framework. His work bolsters the community and helps the ecosystem to thrive. People like Ralph make open-source special and push software engineering forward.
I hope you enjoy the knowledge he has worked to compile and share with you in this book. Let it inspire you to try new things and share your knowledge with others.
Tanner Nelson
Creator of Vapor
Ralph Kuepper has worked in the web and software industry for over 15 years. He started his own company when he was 17 years old while still attending high school and college. Over the years, he has worked on projects for companies such as Adidas, KIA, and Honda. Coming from a traditional background of developing backends and websites using PHP and a monolithic approach, he has embraced and fine-tuned a Swift-based microservice approach for the last 4 years. His company, Skelpo Inc., has been actively involved in the development of the Vapor framework and has contributed a variety of open source microservices as well as related packages.
Caleb Kleveter is a contract software developer for Skelpo Inc. He has been working with Swift for the past 5 years since its release at WWDC 2014 and has been building microservice applications in Vapor for the past 3 years. Caleb also holds a maintainer status on several of the core Vapor repositories, has published several articles on Medium covering how to build backend applications using Vapor and the Fluent ORM, and has spoken at the ServerSide.swift conference on how to build resilient microservice applications in Vapor. Besides Swift on the server, Caleb also enjoys dabbling in other technologies, such as Vue.js, RegEx, and X86 Assembler, and spends his spare time writing streaming text parsers.
If you're interested in becoming an author for Packt, please visit authors.packtpub.com and apply today. We have worked with thousands of developers and tech professionals, just like you, to help them share their insight with the global tech community. You can make a general application, apply for a specific hot topic that we are recruiting an author for, or submit your own idea.
Title Page
Copyright and Credits
Hands-On Swift 5 Microservices Development
Dedication
About Packt
Why subscribe?
Foreword
Contributors
About the author
About the reviewer
Packt is searching for authors like you
Preface
Who this book is for
What this book covers
To get the most out of this book
Download the example code files
Conventions used
Get in touch
Reviews
Introduction to Microservices
What is a microservice?
Rules for using microservices
Understanding why to choose microservices
Effective team management
Reusable code base
Flexible scope of functionality
Maintainability
Scalability
Auto-scaling
Flexible cost
Service-oriented availability
Mixed stacks
Understanding why not to choose microservices
Initially more work
Increased complexity
Debugging and troubleshooting
Who is using microservices?
Amazon
Netflix
Uber
A lot of other companies
Comparing monolith and microservices
Reusable code base
Multiple versions online
No downtime
Updates are as slow or fast as required
Common microservice use cases
Upgrading from monolith to microservices
Decoupling business logic
What does the application do?
What are the common components?
Reorganizing your monolith
Using authentication
Adjusting business logic
Integrating microservices
Summary
Questions
Understanding Server-Side Swift
Technical Requirements
A quick review of Swift
From Fortran to Swift
Swift performance
Scripting languages
Uber
VM languages
Native languages
Comparing frameworks
Swift's features
Swift on the server
Self-contained server
Linux/Ubuntu
Docker
SwiftNIO
Asynchronous events
Features of Swift 5
ABI stability
Raw strings and UTF8 strings
Result type
Future enum cases
Flattening nested optionals
Summary
Questions
Getting Started with the Vapor Framework
The Vapor framework
History of Vapor
Hello World
General structure
Configuration
Middleware
Services
RoutesBuilder
SwiftNIO – futures and promises
EventLoop
EventLoopFutures
map
flatMap
EventLoopPromises
Controllers
Content
Requests
Databases and models
Fluent and FluentKit
A Fluent model
Insert
Update
Delete
Querying
Supported databases
Views
Comparing Vapor to Kitura, Perfect, and Smoke
Vapor and Kitura
Vapor and Perfect
Vapor and Smoke
Installing Vapor
Prerequisites
Vapor in Action
Summary
Questions
Planning an Online Store Application
Technical requirements
Application layout for an online store
Frontend to API communication
Authentification
Generic authentication
Microservice authentication
JSON Web Tokens
Renewing JWTs
Access token
Refresh token
Block access
Database management
Cloud support
User Manager
Models
User
Address
Product Manager
Models
Products
Category
Product Categories
Order Manager
Models
Order
Order Product
Payment
API structure
Summary
Questions
Creating Your First Microservice
Technical requirements
Starting a new service
Version control
Using the API template
General file folders
Dependency management
Adding and removing packages
Configuration
Middleware
CORS
Error
Services
Router
DatabaseConfig
Fluent
Routes
Using models
I/O models
DB models
Returning DB models
Predefined models
Using controllers
Interacting with models
File management
SendGrid
Using workers
Summary
Questions
Application Structure and Database Design
Technical requirements
Understanding project setup and folder structure
Installing Git and Docker
Installing Git
Installing Docker
Using Docker with microservices
Setting up Docker and Git with AWS and GitHub
Setting up Vapor and the database
Setting up our services
Setting up Dockerfiles
Setting environment variables
Running the entire application
Summary
Questions
Writing the User Service
Technical requirements
Setting up and taking the first step
Setting up the template
Installing SendGrid
Setting up a JWT and utility functions
Setting up the database
Exploring routes
Exploring models
Database models
User
Address
Connecting models to Fluent
I/O models
Access token
Refresh token
Response models
Input models
Connecting response models to the database model
Logging in and registering
Preparations
Registration
Login
Refresh access token
Managing users
Preparations
Profile
Update
Delete
Understanding address management
Preparing the controller and routes
Getting addresses
Creating addresses
Updating addresses
Deleting addresses
Starting the service
Summary
Questions
Testing Microservices
Technical requirements
Understanding unit tests
Defining unit tests
Defining functional tests
Setting up Xcode
Unit tests for microservices
Functional tests versus unit tests
Unit test pros and cons
Functional test pros and cons
Trying functional tests via Postman
Installing Postman
Setting up Postman
Testing with Postman
Using isolation as a feature
Reusable services
Controlled testing
Testing multiple services together
Configuration
What to test?
Testing locally
Summary
Questions
Product Management Service
Technical requirements
Setting up the project
Setting up the template
Setting up JWT verification
Setting up the database
Developing routes
Writing the models we need
Creating database models
Creating I/O models
The payload model
Writing the controllers we need
Writing CategoriesController
Writing ProductsController
Testing the service
Summary
Questions
Understanding Microservices Communication
Technical requirements
Understanding when to communicate
Understanding data verification
Understanding data processing
Understanding data aggregation
Understanding data management
Exploring good communication
Asynchronous communication
What to avoid
Understanding Message and Event Systems
Message Systems
Event Systems
REST and WebSocket APIs
Advantages of WebSockets
Defining the interface
Advantages of REST
Leveraging Swift
Shared libraries
Generic functions and classes
Summary
Questions
Order Management Service
Technical requirements
Getting started
Setting up the template
Setting up JWT verification
Setting up the database
Configuring Vapor
Creating our routes
Creating our models
Configuring database models
Writing input models
Writing output models
Creating our controllers
Writing the OrderController
Writing the ProcessingController
Extending the order management service
Adding taxes
Adding payment methods
Adding refunds and coupons
Summary
Questions
Best Practices
Technical requirements
Simplicity for maintainability and stability
Simplicity through libraries
Using straightforward names
Separation of concerns
Embracing Swift language perks
Using extensions
Exploring protocols
Using generic functions
Using abstract and concrete implementations
Combining microservices
Troubleshooting and debugging microservices
Using Xcode for debugging
Using lldb for debugging
Stage and live systems
Summary
Questions
Hosting Microservices
Technical requirements
Setting up a microservice environment
Starting with a simple service
Managing databases and microservices
Using the power of a load balancer
Final setup
Exploring Swift on Linux
The current state of Swift on Linux
Installing Linux on Ubuntu
Running Swift via Docker
Environment variables
Summary
Questions
Docker and the Cloud
Technical requirements
Exploring Docker Containers and Images
Setting up Docker
Images, Repositories, and Containers
Repositories
Images
Containers
Starting Hello World
Running Docker with AWS
Running Docker in Google Cloud
Running Docker with Digital Ocean
Using Kubernetes
Summary
Questions
Deploying Microservices in the Cloud
Technical requirements
Setting up AWS and a Docker repository
Setting up ECS
Using CodePipeline for CD
Summary
Questions
Scaling and Monitoring Microservices
Technical requirements
Scaling microservices and the importance of monitoring
Monitoring
Scaling
Scaling and monitoring using AWS
Scaling and monitoring using Google Cloud
Scaling and monitoring using DigitalOcean
Additional cloud providers
Heroku
IBM Cloud
Microsoft Azure
Oracle Cloud
Summary
Questions
Assessment Answers
Chapter 1: Introduction to Microservices
Chapter 2: Understanding Server-Side Swift
Chapter 3: Getting Started with the Vapor Framework
Chapter 4: Planning an Online Store Application
Chapter 5: Creating Your First Microservice
Chapter 6: Application Structure and Database Design
Chapter 7: Writing the User Service
Chapter 8: Testing Microservices
Chapter 9: Product Management Service
Chapter 10: Understanding Microservices Communication
Chapter 11: Order Management Service
Chapter 12: Best Practices
Chapter 13: Hosting Microservices
Chapter 14: Docker and the Cloud
Chapter 15: Deploying Microservices in the Cloud
Chapter 16: Scaling and Monitoring Microservices
Other Books You May Enjoy
Leave a review - let other readers know what you think
Vapor, written in Swift, is one of the best frameworks available for building scalable and maintainable web applications. Since Swift compiles to a native app, it provides excellent performance while keeping code clean, readable, and easy to learn. It is particularly suited for microservices as Vapor was written with microservices in mind.
Hands-On Swift 5 Microservices Development aims to teach you how to build a next-generation web application. We will work through the development of an e-commerce backend that is written in Swift using the Vapor framework. You will explore how microservices operate together best and what is important for them.
We'll start by introducing microservices first and explaining how they operate. Then we will look at Swift on the server and which options we have. After that, we will combine the two and start working on Swift microservices. Throughout the course of the rest of the book, we will cover everything from writing user management services all the way to deploying the services on cloud platforms. After reading this book, you should have everything you need to write your own applications.
Hands-On Swift 5 Microservices Development has been written for any Swift developers, either iOS, macOS, tvOS, watchOS, or iPadOS, who want to use the same language they have learned to love for server backends as well. If you also already know some server-side Swift, you might find this book interesting as it introduces how to write microservices. Knowing a little bit of Swift is required to read this book but you don't need to know it all; we will go over everything you need as long as you know basic Swift.
Chapter 1, Introduction of Microservices, starts off the book by introducing the concept of microservices and how they are used. Besides the concept itself, some real-life examples are examined and used to illustrate the value of microservices.
Chapter 2, Understanding Server-Side Swift, deals with the current state of Swift on the server, taking a deep look into the internals of Swift and its appeal for server development. The unique features of Swift 5 are also addressed in light of server development.
Chapter 3, Getting Started with the Vapor Framework, introduces Vapor as the leading framework for server-side Swift, exploring how Vapor operates and what Vapor applications look like.
Chapter 4, Planning an Online Store Application, starts the process of writing our example backend for an e-commerce app. We will plan it to demonstrate how microservice applications should be planned.
Chapter 5, Creating Your First Microservice, guides you on how to develop your first microservice. We will write a template service that we can use to develop the services of our demo application.
Chapter 6, Application Structure and Database Design, walks you through setting your system up for microservices, taking a quick look at Docker environments. How to run microservices is also discussed to allow easy microservice development.
Chapter 7, Writing the User Service, begins to put everything together by writing the first service of our e-commerce backend. A user service serves as the central user authority to verify users and in this chapter, we go into a detailed discussion about what this looks like.
Chapter 8, Testing Microservices, deals with the concept of testing microservices and how that is best done. We will look into unit and functional testing and which is used when.
Chapter 9, Product Management Service, covers writing our second microservice for the backend. Products are a central element in e-commerce and this chapter discusses what a service for such objects looks like.
Chapter 10, Understanding Microservices Communication, explains that when our microservices need to communicate, we want to maintain some rules. In this chapter, we look at what, exactly, inner microservice communication should look like and what to avoid.
Chapter 11, Order Management Service, uses the knowledge from the previous chapters to write a service that actually communicates with other services. We also address how external services can be integrated.
Chapter 12, Best Practices, discusses some general best practices for Swift, but specifically for microservices.
Chapter 13, Hosting Microservices, deals with the fact that hosting microservice applications is not the most trivial task. In this chapter, we explore what hosting microservice applications look like and what we need to do so.
Chapter 14, Docker and the Cloud, follows on from learning about the general hosting of microservices by looking at which cloud providers enable us to do it and how.
Chapter 15, Deploying Microservices in the Cloud, covers bringing our example backend online. We will walk through the entire setup on AWS ECS and will then set up a Continuous Deployment (CD) to automatically deploy our code.
Chapter 16, Scaling and Monitoring Microservices, discusses how we can scale microservices in cloud setups. We will take a look at the most common cloud providers and their strategies.
This book is for people who have worked with Swift before, on any platform. As long as you have a basic understanding of Swift, you should get along alright. I'm assuming you are operating on a macOS system that is running the newest version and that Xcode 11 or newer is installed. It will be beneficial if you have worked with servers before, even if not Swift servers. Also, if you have worked with any databases before and have a foundational understanding of how relational databases operate, that will be helpful.
You can download the example code files for this book from your account at www.packt.com. If you purchased this book elsewhere, you can visit www.packtpub.com/support and register to have the files emailed directly to you.
You can download the code files by following these steps:
Log in or register at
www.packt.com
.
Select the
Support
tab.
Click on
Code Downloads
.
Enter the name of the book in the
Search
box and follow the onscreen instructions.
Once the file is downloaded, please make sure that you unzip or extract the folder using the latest version of:
WinRAR/7-Zip for Windows
Zipeg/iZip/UnRarX for Mac
7-Zip/PeaZip for Linux
The code bundle for the book is also hosted on GitHub at https://github.com/PacktPublishing/Hands-On-Swift-5-Microservices-Development. In case there's an update to the code, it will be updated on the existing GitHub repository.
We also have other code bundles from our rich catalog of books and videos available at https://github.com/PacktPublishing/. Check them out!
Feedback from our readers is always welcome.
General feedback: If you have questions about any aspect of this book, mention the book title in the subject of your message and email us at [email protected].
Errata: Although we have taken every care to ensure the accuracy of our content, mistakes do happen. If you have found a mistake in this book, we would be grateful if you would report this to us. Please visit www.packtpub.com/support/errata, selecting your book, clicking on the Errata Submission Form link, and entering the details.
Piracy: If you come across any illegal copies of our works in any form on the Internet, we would be grateful if you would provide us with the location address or website name. Please contact us at [email protected] with a link to the material.
If you are interested in becoming an author: If there is a topic that you have expertise in and you are interested in either writing or contributing to a book, please visit authors.packtpub.com.
Please leave a review. Once you have read and used this book, why not leave a review on the site that you purchased it from? Potential readers can then see and use your unbiased opinion to make purchase decisions, we at Packt can understand what you think about our products, and our authors can see your feedback on their book. Thank you!
For more information about Packt, please visit packt.com.
In this first chapter, you will get to know the basics of microservices. They have been an upcoming trend over the last few years and gained popularity particularly amongst start-ups and projects that are built to grow. Their appeal is that they are designed to be scalable but also offer great flexibility to the programmer. By the end of this book, you will be capable of writing your own microservices for apps and frontends using the Swift framework, Vapor. This chapter will give you an overview of what microservices are and how they are useful in web development.
Microservices are small, individual services that form an application by working together. In contrast to that, monoliths are applications that are operating out of one central service that does not depend on other services. Most traditional off-the-shelf systems such as WordPress and Drupal are monoliths.
Both microservices as well as their counterpart, monoliths, are central elements of modern web development and before you start developing your own, you should understand the essential theory for their usage. You will specifically explore the following topics in this chapter:
What is a microservice?
Understanding why to choose microservices
Understanding why not to choose microservices
Who is using microservices?
Monolith versus microservices
Upgrading from monolith to microservices
After reading this chapter, you will be prepared to start working on your microservices.
Let's quickly define what we mean when we use the term microservice.
As the word already gives away, microservice consists of micro and service. Micro is smaller than small. A microservice by definition should be as small as possible. The other word, service, refers to the function of a microservice: it should do something for us. In this book—and in general—we call them microservices, the plural form of microservice. We do that because a microservice usually operates together with other microservices. A microservice application consists of multiple microservices working together and alongside each other.
Almost all major players, such as Google, Amazon, and Facebook, started out as so-called monolithic applications. What does that mean? In essence, a monolith is an application that operates as one large code base. Popular examples include WordPress, Joomla!, Magento, and Drupal; they typically run on one server for the frontend, PHP oftentimes. If you need to scale such an application, you would add more frontend servers that all do the same thing; they are replicas of each other.
While that would solve the demand issue, another problem exists as well: every time the web page is updated, by changing the source code, a single error could bring down the entire web page. The dominant web technologies for so-called monolith web applications used to be primarily PHP and some used to be Java and Perl. Wikipedia, Yahoo!, Facebook, and many others rely on PHP to this very day. Over time, additional scripting languages such as Python and Ruby entered the race. However, the following problem prevailed: changing source files could introduce bugs and bring down the entire site because every PHP file is usually somehow connected to the others. As the companies grew, they adopted another approach, which has proven to be much more reliable for continuous growth and maintainability. The approach, microservices, includes the idea that a web application does not consist of one big monolith anymore but is divided up into many independent services that work together.
The approach itself is not all that new; logistic companies had implemented such a strategy for their structures as well. But growing internet tech companies used this method to solve two of their main problems:
Scalability:
Individual services are much easier to scale than scaling the entire system.
Maintainability:
When changing or adjusting one service, it will not affect the other services, which creates a more solid and stable system overall.
Now, not only the general approach has changed but also the field of programming languages. While in early 2000 just a couple of languages were used for developing web applications, we have a lot more options such as Swift, Go, Python, and JavaScript that are available now.
For all of the intents and purposes of this book, let's use the following definition of microservices: a microservice is a small service that runs along with other services and builds the application together with the other services.
There is no actual official definition of what a microservice is and is not; however, the following rules generally apply to commonly used microservices:
A small unit of a backend infrastructure
Operating as independently as possible (meaning, no or little communication with other microservices)
Performing a service (such as processing data or offering an API)
Offering as little functionality as reasonable
Operates with its own database
To conclude, a microservice is the smallest and most isolated unit possible of the business logic and is needed for the server application. Now, let's look at the cases when microservices are a great choice!
Let's look at some of the reasons why you might want to choose microservices for your applications. Not every application should utilize microservices, as you will see in the next section. Very distinct reasons warrant the use of microservices. Let's take an example to justify why we want to choose microservices.
Let's pretend you want to develop a simple e-commerce app. If we say that there are three different elements of microservices in an app, User, Product, and Order. The app should cover the following features:
User: Log in
User: Register
User: Change addresses
User: Change payment methods
Products: Show the list of products in a category
Products: Show details about an individual product
Order: Submit an order of products
Order: Submit payment for an order
You could develop the backend for such an app as a monolith, of course. It would, without a doubt, be a rather big application and require many models and controllers. But if you were to develop the same app with microservices, you could end up with three more flexible packages, such as the following:
User Manager
Products Manager
Order Manager
You can now enjoy the following benefits from using microservices:
Effective team management
Reusable code base
Flexible scope of functionality
Maintainability
Scalability
Mixed stacks
Let's dive into each of these sections now.
If you have ever worked in a team on a bigger monolithic application, you know very well how chaotic and unorganized it can get. Various preferences, styles, and trains of thoughts are commonly joined together, resulting in a decently sized mess.
With microservices, you can assign different services to different team members. In the preceding example, if you happen to be a three-member team, each one of you could develop one service. The added efficiency will not just increase productivity in the beginning but carry through the entire project.
Spreading out the workload across multiple people working separately but still together is a significant benefit for all of the teams. Imagine you have to manage 500+ programmers for a big project (think Facebook or Google). It is close to impossible to function well over a longer period of time if everyone is using the same code base. If the application is split up into small microservices, you can have a lot of 10-people teams that are working on various services. While this comes with its own challenges, it will certainly reduce the potential for error in the code itself.
But even if you happen to be in a small team, few developers can experience a noticeable increase in productivity when developing microservices.
In essence, microservices allow you to spread work out effectively in a team.
For the sake of this discussion, let's assume that you have already written a user manager once before and now you can use it again. With microservices, you can use and reuse any given service that you have developed previously. If a service does not quite fit your case, you could just modify it instead of writing it from scratch.
Reusing the same code across multiple projects saves you valuable time and resources. You may even start thinking about microservices abstractly so that you purposefully can reuse the services. You can try to define a set of functions that fit more than one project for you to reuse with other projects.
Let's take a look at the aforementioned user manager service. Almost all applications that interact with users have a login. In most cases, the functionality is pretty much identical, as shown here:
Log in via email and password
Registration with email verification
Forgot password; send recovery email
Log out
Delete account
Once you have written this service you can easily implement it with other projects.
Another similar case is when you are choosing a SaaS solution for user management. Examples include AWS Cognito, Auth0.com, Okta, and Backendless. Microservices allow you to easily incorporate such services to save yourself the time and effort of writing a user management solution at all in this case. Naturally, the same principle applies to other types of services as well.
To summarize, microservices allow you to reuse existing code for new projects and save time and effort. Next, let's explore the scope of functionality.
We know that this app will grow and that users will need more features. Microservices are ideal for such cases because you can simply add more services for functionality or modify the ones that you already have. Take the earlier example; you start out with a very manageable and small set of features. If you know these are all of the features you will ever need, there would be no reason for not using a simple monolithic approach for this. The reality, however, is that many projects grow, both in terms of users and mostly in terms of what they offer. You may decide to add functionality to your offering or to significantly change it.
Imagine you need to add a new payment method to your online shop. In a monolith, you need to work on and deploy the entire application, which comes with risks. However, in microservices, if you have the order manager, you can simply add the payment method to that service and deploy it and you are good to go. The user manager and product manager do not need to be touched.
Microservices allow you to grow your functionality as you need and without needing to touch other parts of the software.
It makes a lot of sense to use microservices not only when your specifications may change, but also in cases where your requirements are highly defined. Microservices are easily maintained; each service can be updated, upgraded, and serviced individually without influencing the other services. This is particularly important with bigger applications as it reduces the risk and impact of potential downtime.
If you are serving a lot of users, you want to avoid downtime as much as possible. Because microservices are independent, you can replace them in time without going offline. You will explore deployments later on in more detail, but most cloud service providers have procedures in place that will keep your application up 100% of the time while switching out the services.
Additionally, you and your team can focus your efforts on the services that need it most. While one service is being heavily updated, the other services can stay the way they were. I have been in a project that had legacy microservices running for over two years because it worked reliably and effort was put into developing new features instead of updating the old ones. You should not neglect updating all parts of your system though, but microservices allow you to keep old infrastructure longer than with a monolith.
In conclusion, microservices allow you to work on them while other services stay as they are and therefore give you the ability to focus on what matters most.
Another element to consider is that you want to be able to grow and scale your application easily. Microservices are arguably the easiest form of application for a server application to grow. Remember, we have individual and independent services running. It means, in principle, that no problem should have the same service run in many instances, for example, you could have 100 servers running the same service. Alternatively, it could also run as only one service, based on your needs.
Let's look into the following three distinct advantages microservices have when it comes to scalability:
Auto-scaling
Flexible cost
Service-oriented availability
You can have your hosting provider automatically scale (up and down) according to your needs. Predefined and customizable rules allow you to define and to scale up and down. If you have an upcoming marketing gig (such as a TV promotion), your backend will automatically scale according to your demand without you having to adjust anything manually.
This goes hand-in-hand with auto-scaling. You may pay for the infrastructure depending on your needs. In an ideal world, you would pay nothing for no users and increasingly more as you have more users. In reality, this rarely happens just like that, however, you do end up saving money as you don't need to buy more hardware than you need in most cases.
Often, not every service is used equally. In the preceding example, the user service only performs authentication and registration. Once the user is authorized, this service is mostly irrelevant to the app. You may decide to have the email processing service to be a lot more available than your user service.
Concretely, this may look like five servers are running the product manager application while only one server runs the user and the order manager. As your app grows and changes, you can adjust this setup precisely to what you need.
So, we can conclude that microservices allow your application to grow effortlessly and you have many options for how you want your entire backend application to run.
Sometimes, you may find yourself in a situation where a part of your tech stack is using other technologies. You may want to write your microservices with Vapor and Swift but have a good bit of infrastructure in PHP. You can utilize microservices to keep some of the old parts while already developing new services. Your setup will then look like the following diagram:
In this case, your user request will be routed either to the (old) PHP monolithic Media & File Management service or to your new Vapor services. Your old monolith is actually turned into a microservice itself, though it most likely covers more functionality than you want it to have. But, deciding to go with microservices allows you to incorporate software that you may depend on even if it is written in an entirely different language.
If you are wondering how the preceding example would look like in real life, most microservices are operating out of containers (for example, Docker containers). These containers operate as mini-servers and are completely isolated. So, even with just one actual hardware server, you can implement the preceding scenario with a local load balancer such as nginx.
Hence, microservices allow you to integrate older parts of your infrastructure while already using your newer parts.
You have seen several reasons to choose microservices. Now, let's look at reasons why not to choose microservices. As with everything, the strengths of microservices are also their weakness. While this book is about writing microservices, you should not think that microservices are the answer to every problem. There are many examples of why microservices are actually the wrong choice for certain problems. Here is a list of some of the reasons why not to choose microservices.
The first and most obvious reason why you would not want to choose microservices is that it is usually a bit more work initially. To set up the entire system and connect the services and get them all up and running the way you need to often requires more work than with a monolithic application.
It starts by setting everything up and building a working environment. A monolithic application will require you to run the application only. So, once you start your main application, you are good to go.
A microservices application, however, requires a setup in which multiple applications are running at the same time. Alternatively, you could design your application to receive test data from static files; this, however, does not replace testing with the actual services. You can archive such a setup easily in a deployment situation; cloud providers are doing an excellent job in helping us here. However, when you start developing, it can be a good amount of work to set everything up. In the next chapter, you will set up your own workspace.
Additionally, microservices demand planning. You cannot perform some changes as quickly as you would in a monolithic application. If you are only building a simple proof-of-concept for your backend, you might be better off starting as a monolith. If you need something implemented that is critical in timing, microservices might not be your best option.
So, a good thing to keep in mind when working with microservices is that microservices demand some planning and often take longer to start.
When developing monolithic applications, you usually have everything in the same code base. As long as a project is small, the lack of complexity makes it easier for you to maintain it. Additional features and changes can be implemented with the same stack, language, and frameworks you have been using so far.
Microservices, on the other hand, can be a bit more complex (or messy even). Adding a new feature is not always trivial and may require changes in numerous services. The services themselves may also have different stacks. You may have a legacy service running PHP combined with a Swift Vapor service for another part of the app. Adding a feature requires you to work in PHP as well as Swift.
If you know your exact scope for a project and don't expect any changes, there is no reason not to implement it like a monolithic application.
Microservices can increase the complexity of a project, compared to traditional technologies such as PHP, which you should keep in mind. The same can be said about most microservice technologies though, regardless of programming language. Let's take a look at troubleshooting and debugging now.
Debugging and troubleshooting is yet another issue you will need to consider. It can be quicker and easier to debug one application as opposed to two or more microservices. Debugging goes hand in hand with complexity; bugs will not be found as quickly as they can be in a monolithic application. As a matter of fact, this topic is important enough for this book to have an entire chapter on it.
If you are dealing with an application that is limited in scope and functionality is not expected to grow, a monolithic approach might be better than a microservice approach. That said, I have personally seen many projects start as "small and manageable" pretty suitable for monolithic applications. But then they grow, and the benefits quickly turn into serious problems. If you think all of your applications should be suitable for growth, take a microservice approach.
It can take more time to find bugs. Because services are often somehow connected, it can be pretty hard to boil a symptom down to a bug. I have seen a small symptom come out of many unrelated errors.
To conclude, debugging a microservice backend is more complex and time-consuming than for monolithic applications, however, there are also great benefits with using them. This is why we will look at a list of companies that are using microservices and have switched away from monoliths.
After learning about the pros and cons of microservices, let's take a look at who is using them. The following examples are not exclusive and were selected with modern web applications in mind. If you want to develop an app that has the potential to become as big as Netflix, why not check out how things work well for them?
It will probably be no surprise to learn that Amazon is one of the first big companies that utilized the internet and implemented microservices. Amazon, like many others, started out by being a big monolithic application. As it grew, additional programmers were hired and started working on the application. As you can imagine, over a hundred developers all working on the same code base will ultimately result in chaos and conflicts. This also happened in the years around 2000; so many modern tools (such as Git) were not nearly as advanced as they are today. Back then, Amazon began to break the big application up into more manageable and usable sub-units, called microservices.
Amazon is now deploying every 11.7 seconds (https://blog.newrelic.com/technology/data-culture-survey-results-faster-deployment/). Despite the challenge of having to enable hundreds of developers to work on the platform, Amazon also solved another problem: growth. Because amazon.com runs as a microservice application, it has no downtime. Amazon can take as many visitors as it gets because the system is managing itself.
By the way, Netflix, Uber, and many others are using Amazon Web Services (AWS
