34,79 €
This book is about building professional web applications and web services using Swift 4.0 and leveraging two popular Swift web frameworks: Vapor 3.0 and Kitura 2.5. In the first part of this book, we’ll focus on the creation of basic web applications from Vapor and Kitura boilerplate projects. As the web apps start out simple, more useful techniques, such as unit test development, debugging, logging, and the build and release process, will be introduced to readers.
In the second part, we’ll learn different aspects of web application development with server-side Swift, including setting up routes and controllers to process custom client requests, working with template engines such as Leaf and Stencil to create dynamic web content, beautifying the content with Bootstrap, managing user access with authentication framework, and leveraging the Object Relational Mapping (ORM) abstraction layer (Vapor’s Fluent and Kitura’s Kuery) to perform database operations.
Finally, in the third part, we’ll develop web services in Swift and build our API Gateway, microservices and database backend in a three-tier architecture design. Readers will learn how to design RESTful APIs, work with asynchronous processes, and leverage container technology such as Docker in deploying microservices to cloud hosting services such as Vapor Cloud and IBM Cloud.
Das E-Book können Sie in Legimi-Apps oder einer beliebigen App lesen, die das folgende Format unterstützen:
Seitenzahl: 377
Veröffentlichungsjahr: 2018
Copyright © 2018 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:Karan GuptaContent Development Editor:Francis CarneiroTechnical Editor:Akhil NairCopy Editor:Safis EditingProject Coordinator:Pragati ShuklaProofreader:Safis EditingIndexer:Mariammal ChettiyarGraphics:Alishon MendonsaProduction Coordinator:Nilesh Mohite
First published: November 2018
Production reference: 1301118
Published by Packt Publishing Ltd. Livery Place 35 Livery Street Birmingham B3 2PB, UK.
ISBN 978-1-78934-117-1
www.packtpub.com
Mapt is an online digital library that gives you full access to over 5,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
Mapt is fully searchable
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.
Angus Yeung works for Intel, and is responsible for the architectural design of backend cloud services for virtual reality sports broadcasting. He is also a computer science lecturer at San Jose State University. Prior to Intel, he held CTO and engineering director positions at several companies, including a start-up he founded in 2002.
Angus' technical interests include mobile computing, distributed computing, computer vision, and artificial intelligence. He holds an BS, MS, and PHD in Electrical Engineering from Univ. of Rochester, and an MBA from UC Berkeley. Angus owns 18 pending and granted patents. Angus lives with his lovely wife and three handsome boys in Palo Alto, California.
Tibor Bödecs is an enthusiastic software developer with more than a decade of experience in the IT industry. In his past, Tibor was the technology leader at one of the biggest mobile development-focused companies in Hungary. He is a self-taught programmer with a true passion for Swift from the very beginning. He has a good ability to work with different languages, technologies, and extensive experience in product management. Nowadays he is a freelancer developer focusing mostly on web, mobile, and server-side Swift projects. Tibor has a personal blog where he regularly writes about the Swift programming language.
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 Server-Side Web Development with Swift
About Packt
Why subscribe?
Packt.com
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
Introducing Server-Side Swift
Introducing Swift
Open sourcing Swift and components
Swift compiler
Swift standard library
Swift foundation framework
Dispatch framework
XCTest testing framework
Swift Package Manager
LLDB debugger
CommonMark documentation
Bringing Swift to the server-side
SwiftNIO
Surveying Swift server-side frameworks
Vapor
Kitura
Perfect
Choosing the right framework
Performance
Feature sets
Ecosystem
Community support
Vapor
Kitura
Perfect
Summary
Getting Started with Vapor and Kitura
Installing Vapor and Kitura on Mac
Preparing your Mac for server-side Swift development
Installing the Xcode IDE on your Mac
Installing Xcode Command Line Tools
Installing Homebrew
Installing Vapor Toolbox on Mac
Checking your system's compatibility with Vapor
Installing Vapor Toolbox using Homebrew
Verifying Vapor installation
Installing the Kitura CLI on Mac
Installing Vapor and Kitura on Ubuntu
Working with the Ubuntu APT
Installing the Swift Toolchain on Linux
Installing Vapor on Ubuntu
Option 1 – using script to clone Vapor packages
Option 2 – cloning Vapor packages manually
Installing Vapor on Ubuntu
Installing Kitura on Ubuntu
Installing required Linux system packages
Exploring Vapor Toolbox and the Kitura CLI
Using Vapor Toolbox Commands
Getting help on a specific Vapor command
Exploring the Kitura CLI
Using KAG
Selecting a scaffolded application
Choosing additional services
Summary
Building Your First Web App
Creating an app using Vapor CLI
Creating a hello world app from a template
Building the hello world app
Running the hello world app
Converting to the Xcode project on a Mac
Reviewing source code in Vapor boilerplate
Adding more routes in Vapor
Creating an app using Kitura CLI
Creating a hello world app from a default template
Running your Kitura app from a Terminal
Running your Kitura app from Xcode
Testing the app with a web browser client
Reviewing source code in Kitura boilerplate
Adding more routes in Kitura
Summary
Debugging and Testing
Writing tests for server-side Swift projects
Preparing a test executable target
Writing tests using XCTest
Checking out test cases in a Vapor boilerplate project
Learning useful assertion macros
Adding a unit test to your project
Running unit tests in Xcode
Checking code coverage
Turning on code coverage
Generating a coverage report
Reviewing Kitura boilerplate tests
Handling asynchronous tests
Using extensions for functions common to all tests
Debugging in a server-side Swift project
Using the Logging API in a Vapor project
Using the Logger API in a Kitura Project
Debugging using the HTTP traffic monitoring tool
Debugging using Postman
Debugging using the curl command in the Terminal
Summary
Setting Up Routes and Controllers
Adding custom routes in a Vapor project
Modeling your data with content type
Using controller for logical operations
Using Vapor's route collection
Grouping related routes
Implementing route handlers
Retrieving all entries
Creating a new entry with a unique ID
Retrieving an entry
Updating an entry
Deleting an entry
Testing the routes
Adding custom routes in a Kitura project
Modeling Codable data
Using controllers for logical operations
Implementing Codable routing
Handling Kitura routes
Summary
Working with Template Engines
Using the Leaf templating engine in Vapor
Configuring the Leaf templating engine
Using the basic functions of the Leaf templating engine
Using variables and tags in Leaf templating
Setting a variable
Working with context
Looping through a collection
Checking conditions
Embedding other templates
Adding more Leaf templates
Displaying all journal entries
Completing the features
Templating with Stencil in a Kitura project
Learning the basic functions of the Stencil templating engine
Using variables and tags in Stencil templating
Summarizing useful filters and tags in Stencil
Configuring the Stencil templating engine
Developing code working with Stencil templates
Adding Stencil templates to your Kitura project
Displaying all journal entries
Completing the features
Creating a new journal entry
Editing a journal entry
Removing a journal entry
Summary
Bootstrapping Your Design
Getting started with the Bootstrap framework
Setting up for Bootstrap
Inserting the stylesheet
Adding dependency for JavaScript files
Using a starter template in Bootstrap
Using basic Bootstrap components
Organizing content into grids
Displaying a jumbotron with parallax animation
Adding a navigation bar
Using form controls
Reusing glyphicons
Using Bootstrap for a Vapor application
Enhancing Leaf templates with Bootstrap
header.leaf
footer.leaf
main.leaf
new.leaf
entry.leaf
Using Bootstrap for Kitura
Enhancing Stencil templates with Bootstrap
header.stencil
footer.stencil
main.stencil
new.stencil
entry.stencil
Summary
Employing Storage Framework
Installing databases
Installing PostgreSQL
Installing SQLite
Installing MySQL
Working with the Fluent Framework in Vapor
Choosing a database driver
Using the PostgreSQL database driver
Using the SQLite database driver
Using the MySQL database driver
Conforming to the Fluent Model
Creating a new Model
Creating Fluent Migrations
Using Fluent Model Helpers
Implementing CRUD operations for Vapor
Implementing the create operation
Implementing the read operation
Implementing the update operation
Implementing the delete operation
Working with the Database Abstraction Layer in Kitura
Choosing a database driver
Using the PostgreSQL database driver
Setting up the SQLite database driver
Using the MySQL database driver
Conforming to the Swift-Kuery-ORM Model
Creating a new model
Implementing the CRUD operations
Displaying all records
Displaying a single record
Creating a new record
Updating an existing record
Deleting a record
Summary
Adding Authentication
Introducing the authentication API for Vapor
Using web authentication
Setting up AuthenticationProvider
Configuring for SessionMiddleware
Constructing a Model
Accessing protected content
Adding public routes
Adding the login page
Checking login credentials
Logging out of the current session
Specifying protected routes
Using the authenticated state
Managing accounts
Listing all accounts
Adding a New Account
Removing an account
Seeding databases
Introducing authentication for Kitura
Setting up HTTP basic authentication
Constructing a Model
Using TypeSafe HTTP authentication
Summary
Understanding Technologies for Web Services
Serving clients with web services
Designing three-tier architecture for web service
The frontend layer
The application layer
The data storage layer
Reviewing HTTP protocols
Designing the cloud frontend with pattern
The backends for frontends pattern
API gateway
Encapsulating business logic into microservices
Implementing a microservice-oriented architecture
Designing microservice with key principles
Cloud deployment
Containing microservices with Docker
Continuously deploying to the cloud
Working with a sample workflow
Summary
Designing for API Gateway
Serving clients with the RESTful API
Understanding the server/client model based on HTTP
Designing the RESTful API
Identifying object models
Defining resource endpoints
Defining endpoints for top-level resources
Defining Endpoints for Sub-resources
Assigning HTTP methods
Browsing all journal entries
Creating a new journal entry
Getting a specific journal entry
Editing a specific journal entry
Deleting a specific journal entry
Implementing the endpoints and responses
Implementing Handlers for Public Routes
Implementing handlers for admin routes
Creating a new item
Retrieving an item by ID
Updating an item
Deleting an Item
Implementing API endpoints for Kitura
Creating a new project for the Kitura web service application
Working with the Kitural model
Setting up a database
Adding route handlers
Retrieving all items
Creating a new item
Retrieving an item by ID
Updating an item
Deleting an item
Deleting All items
Summary
Deploying to the Cloud
Deploying Vapor web service to Vapor Cloud
Checking out Vapor Cloud features
Database and Cache Support
Application Monitoring
Recurrent Job Scheduling
Accessible to File Storage and CDN Services
Zero-Downtime Deployment
Signing up Vapor Cloud
Deploying to Vapor Cloud
Using the Vapor Cloud commands
Creating Your First Deployment
Creating an Application from Git Remote
Working with Slug and Environment
Choosing a Replica Size and Database
Choosing a Build Type
Managing Your Cloud application
Getting live log output
Working with environment variables
Adding a custom domain
Scheduling a New cronjob
Deploying the Kitura web service to IBM Cloud
Working with an IBM Cloud Account
Registering for an Account on IBM Cloud
Working with the IBM Cloud Dashboard
Readying the Local System for IBM Cloud Deployment
Installing IBM Cloud Developer Tools
Using IBM Cloud Developer Tools
Creating a Kitura app that is deployable to IBM Cloud
Generating a Starter Kitura Web Application
Logging into IBM Cloud
Building Your App with the IBM Cloud Tool
Running the Kitura App in the Local Container
Deploying Your app
Summary
Developing an iPhone Client
Developing an iOS App for a server-side Swift application
Creating a new project
Creating a new TableViewController
Adding content to TableViewController
Preparing your data model
Configuring table properties
Adding a label to the prototype cell
Constructing route handlers for web services
Adding domain exceptions for App Transport Security
Testing the Vapor Server app
Running the iOS app
Adding a new entry to journal
Designing the user interface for a new entry
Using the Delegate Pattern
Hooking up new functionalities for UI items
Steps to Make Requests to the server
Preparing for Encoded JSON Data
Configuring an Upload Request
Starting an Upload Task
Putting Everything Together for the upload task
Finishing the CRUD operations
Editing an existing entry
Creating the EditEntry segue
Adding a new function to the delegate protocol
Making an HTTP PUT request
Configuring the user interface to edit an entry
Deleting an existing entry
Summary
Developing Microservices
Leveraging Microservices in Backend Applications
The microservice-oriented architecture
Design Principles of the Microservice Framework
Deploying a Containerized Application to a Cluster
Working with Containers and Orchestrations
Understanding the Container Deployment workflow
Publishing a Docker image to IBM Cloud Registry
Logging into IBM Cloud
Working with the Docker CLI
Tagging Your Docker Image
Deploying a Docker Image to IBM Cloud Registry
Creating a Cluster on IBM Cloud
Setting up the Kubernetes CLI
Downloading the Cluster Configuration
Creating a Deployment Using Container Registry
Exposing the deployment and launching the app
Summary
Vapor Boilerplate Project
Reviewing Vapor-generated files
Installing tree to view the file structure
Reviewing a Vapor project's file structure
Understanding the file structure in a Vapor project
Configuring Swift Package Manager
Package dependencies
Build targets
Starting with an entry point
Instantiating an application object
Configuring before instantiating application
Adding initialization code after application instantiation
Registering the application's routes
Implementing endpoint logic in controllers
Using a data model
Kitura Boilerplate Project
Reviewing Kitura-generated files
Reviewing a Kitura project's file structure
Understanding the file structure in a Kitura project
Understanding generated sourcecode in Kitura
Configuring using Swift Package Manager (SPM)
Starting with the entry point
Declaring application classes
Handling errors
Setting up monitoring metrics
Setting up health check endpoints
Other Books You May Enjoy
Leave a review - let other readers know what you think
Swift is a strongly and statically typed programming language that has been used extensively for client-side development in iOS, macOS, tvOS, and watchOS. The open source developer community has brought Swift to the Linux platforms, making Swift a cross-platform programming language. This book will get you started with Vapor and Kitura by teaching you about development workflows, unit tests, and the build and release process. You'll then dive into the details of designing web applications with template engines, the Bootstrap framework, databases, and user authentication. Finally, you'll move on to building APIs for web services, full-stack development with iOS applications, and deploying web services as containerized application.
This book is for anyone interested in building professional web applications and web services using Swift and two popular Swift web frameworks: Vapor 3.0 and Kitura 2.5.
Chapter 1, Introducing Server-Side Swift, explains why you should extend Swift for server-side development on Linux and take advantage of using Swift for both server- and client-side development. You will survey an array of popular web frameworks in Swift and learn about the merits of each of them. If you are interested in starting the journey of developing web apps and services using Swift, you will find the chapter's recommendations for references, online resources, forums for discussion and technical questions, and the list of developer community support very helpful.
Chapter 2, Getting Started with Vapor and Kitura, aims at getting you started with both Vapor, a server-side framework with very strong developer community support, and Kitura, a server-side framework with backing from IBM. You'll be introduced to Vapor Toolbox, a command line interface (CLI) that allows you to rapidly develop Vapor apps from boilerplate Vapor projects. You'll follow step-by-step guidance to install Vapor Toolbox on macOS or Linux, and then check your system's readiness by using Vapor CLI tools to verify system compatibility with required development environment. Similarly, you'll be introduced to Kitura development workflows and follow step-by-step instructions to install Kitura tools and libraries on your system.
Chapter 3, Building Your First Web App, takes you directly to server-side Swift coding with detailed instructions on creating a new web app project from a template provided in a web framework. You'll be guided on how to create, build, run, and test a "Hello World!" web app using Vapor 3.0. After that, you'll learn how to expand the features of the web app by adding more new routes to handle additional requests from clients. You will continue your journey to create a similar "Hello World!" web app with the Kitura web framework. After going through the exercises of building a simple web app with both Vapor and Kitura, you'll be able to note the similarities between the two web frameworks and appreciate the different approaches taken by them.
Chapter 4, Debugging and Testing, introduces the basics of the agile development process and recommends some of best practices in developing, debugging, and testing server-side Swift code. When it comes to web development frameworks, both Vapor and Kitura offer very good logging and debugging support. You are going to learn how to use the logging and unit test features to help in debugging and error-proofing your code.
Chapter 5, Setting Up Routes and Controllers, dives into the details of handling custom requests with routes and controllers. A route is an object used to represent a custom request embedded in a URL and a controller is the component that contains the business logic to handle the request routed to it. You'll learn how to add custom routes for requests, create controllers to handle the routes, and construct responses for the requests. You'll manipulate custom parameter types and process a group of routes in a collection. Finally, you'll learn how to take advantage of the Codable class in Swift to encode and decode complex JavaScript Object Notation (JSON) objects in easy ways.
Chapter 6, Working with Template Engines, introduces you to two template engines: Leaf for Vapor and Stencil for Kitura. Templating languages allow you to work with content automatically generated by a script. For dynamic content, you'll learn how template engines help in accelerating the development of dynamic web pages. Dynamic content creation is useful when presenting results of data that is generated at runtime and not known beforehand. For static content, you'll learn how template engines help ensure a consistent structure with features such as headers, footers, color schemes, and backgrounds. You'll also be introduced to the nuts and bolts of Leaf and Stencil templating languages and learn how to use variables in template scripts to communicate information between Swift classes and script functions.
Chapter 7, Bootstrapping Your Design, introduces you to the Bootstrap framework, which is a collection of CSS and JavaScript libraries, and explains how the Bootstrap framework allows you to build responsive website easily. You'll follow step-by-step instructions to insert Bootstrap components into your templates and learn how to beautify different UI elements in your template with Bootstrap. Toward the end of the chapter, you'll learn how to include Bootstrap in your project when you are ready to deploy your web apps.
Chapter 8, Employing Storage Frameworks, has you take advantage of the Object Relational Mapping (ORM) abstraction between the web application and the database to streamline your workflow when working with a database. One of the major advantages of using an ORM tool is that you don't have to deal with a database directly, avoiding the painful process of writing different querying commands for each type of database. Swift web frameworks support a number of database engines, and sometimes you can use multiple databases in the same session. In this chapter, you'll learn how to work with the Fluent abstraction framework in Vapor and the Kuery database abstraction layer in Kitura. You'll interact with your model with Create, Retrieve, Update, and Delete (CRUD) operations using these abstraction layers.
Chapter 9, Adding Authentication, introduces you to the key features in user-access management: user authentication, cookies, and sessions management. You'll learn how to set up a user model and password-protected content. With the authentication API, you're going to grant and remove access for different users. You'll then learn how to manipulate cookies and manage user login sessions, and implement logic to authenticate user to get access to protected content.
Chapter 10, Understanding Technologies for Web Services, reviews the underlying technologies that empower web apps and web services. You'll learn the server/client model based on HTTP/HTTPS in more details. For the architecture and design of web services, it'd better to divide the design into a three-tiered architecture consisting of a frontend API gateway, some business logic in the middle, and then backend database services. You'll learn how a typical frontend API gateway is designed, how to encapsulate a middle component with business logic into a standalone microservice, and how to design and work with a backend storage framework.
Chapter 11, Designing for API Gateway, teaches you how to build a RESTful API, introduce you to the basic rules for API design, teach you how to create endpoints for requests that a client sends to a server, and explain how to define response status codes. You'll then learn how the design of a RESTful API can be extended, specifically through the building of API Gateway, which is the single entry point for all clients and routes client requests to different MVC components or microservices.
Chapter 12, Deploying to the Cloud, tells you how to deploy your web services to the cloud. You'll be introduced to popular hosted cloud solutions: Vapor Cloud (AWS) and IBM Cloud (Bluemix). Vapor Cloud is the official hosting service for Vapor and there is built-in support in Vapor CLI to let you deploy and manage your Vapor instance easily without installing additional libraries and tools. Similarly, IBM Cloud is a natural choice of hosted solution for Kitura web services, since both IBM Cloud (Bluemix) and Kitura are IBM cloud solutions.
Chapter 13, Developing an iPhone Client, puts everything you'll have learned so far about server-side Swift together and uses an iOS app to show how a client "journal" app can leverage your PostgreSQL database, and other cloud services that you can build with a Swift web framework. You'll first get started with building a journal iOS app, adding logic and UI components to the app design. You'll create a model for journal data and add the support of CRUD operations for a PostgreSQL database. At the end of this chapter, you'll have a functional journal app that works seamlessly with your web services.
Chapter 14, Developing Microservices, teaches you how to build independent microservices and add them to a Swift web framework. Container technology, such as Docker, is used to deploy and run a Swift package artifact as a microservice. You'll learn how to deploy a Docker container and use container orchestration tool such as Kubernetes to manage and scale the deployment of containerized applications in a cluster.
Appendix A, Vapor Boilerplate Project, gives you a clear understanding of the boilerplate code in Vapor: you'll review Vapor-generated files, examine the file structure in a typical Vapor project, check out the project's configuration in manifest file, and go through the sequence of initialization steps before and after application instantiation. It also explains to you the sample routes, controllers and data model included in the boilerplate project.
Appendix B, Kitura Boilerplate Project, provides you with a better idea with the boilerplate project generated using kitura init. You'll review Kitura-generated files, file structure in a Kitura project, and configuration in the project's manifest file. The work flow in the boilerplate project will be carefully examined. At the end, you'll also check out the metrics-monitoring and diagnostic services already included in the boilerplate code.
Some working knowledge of the Swift programming language would be required. You could be a beginner in terms of Swift programming, a seasoned iOS or macOS developer, or a software developer who wants to work on practical Swift applications while learning the language itself. By the end of the book, you will be able to successfully create your own web applications and web services by leveraging the powerful ecosystem of Swift.
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.packt.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 & Errata
.
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 athttps://github.com/PacktPublishing/Hands-On-Server-Side-Web-Development-with-Swift. 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 athttps://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.packt.com/submit-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.
Swift is a strongly and statically typed programming language that has been used extensively for client-side development in iOS, macOS, tvOS, and watchOS. The open source developer community has brought Swift to the Linux platforms, making Swift a cross-platform programming language. In this chapter, we will explain why the open source developer community has extended Swift for server-side development, and how they have streamlined the workflow for both server and client-side development using the same programming language.
There are several server-side Swift frameworks, and most of them are developed and maintained by the Swift developer community. We will take a closer look at the three top server-side Swift frameworks: Vapor, Kitura, and Perfect. Each of these frameworks has a different set of features and benefits. We hope that you feel comfortable with choosing the right Swift server-side framework for your next server-side project.
In this chapter, we will cover the following topics:
Introducing Swift
Surveying Swift server-side frameworks
Choosing the right framework
Swift is a high-performance modern programming language that was first announced at the Apple World Wide Developers Conference (WWDC) in September 2014. Thanks to Apple's strong support and endorsement from the developer community, Swift has become one of the fastest growing new languages in computer science history. Swift 2.0 was released in September 2015, followed by Swift 3.0 a year later, and Swift 4.0 in September 2017. There have been two additional releases: Swift 4.1 in March 2018 and Swift 4.2 in September 2018.
As a modern language, Swift offers a clean syntax and many modern programming language constructs. Even though Swift is inspired by many other popular programming languages, Swift is an independent language completed with all the core features of a modern language. We will find the familiar low-level constructs in Swift, such as data structure, classes, functions, enums, as well as many useful modern features, such as protocols, optionals, closures, and generics.
Type safety is enforced from the ground up in Swift. The emphasis of type safety shifts the detection of many nasty errors from runtime to compile time. As a result of dramatically reduced runtime errors, Swift developers enjoy relatively increased productivity and an ease of programming.
Swift keeps many of the constructs found in modern programming languages, but also eliminates some features that are frequently seen in other languages. One example is that Swift uses modules instead of headers, eliminating code duplication often seen in using headers. Moreover, Swift does not support exceptions and an automatic garbage collector. In Swift, memory safety is ensured by default. Instead of a garbage collector, Swift uses a thread-safe Automatic Reference Counting (ARC) for an object's life cycle management.
As a compiled language, Swift is very fast at execution. The source code of Swift is first checked for type safety, then compiled into a machine-independent intermediate code in a Low Level Virtual Machine (LLVM) for optimization, and eventually used to generate machine code that is native to the system. Swift's execution performance often matches that of modern native programming languages and exceeds that of interpreted programming languages.
The official version of open source Swift was first launched in December 2015. Since being opened up to wider community support and development, open source Swift continues to grow in both popularity and maturity in terms of the contribution of open source community and the addition of new features. The contributors to open source Swift include Apple, IBM, PayPal, and other industry and academic institutions.
The effort of the open source developer community is coordinated through the Swift programming language evolution (https://github.com/apple/swift-evolution) process. The process governs the evolution of Swift by defining the process for accepting new proposals, stating the goals for upcoming Swift releases, reviewing and tracking the status of proposals, and specifying the decision-making procedure for accepting or rejecting a proposal. The evolution process ensures that Swift can evolve into a robust language while imposing constraints to maintain application binary interface (ABI) stability. With ABI stability, the binary compatibility between applications and libraries is ensured with different Swift versions.
Open source Swift includes more than the specification of the Swift programming language. On the official website of open source Swift, https://swift.org/, there is information on the fundamental components for the language, including the Swift compiler, standard library, package manager, core libraries, test framework, and REPL/debugger.
The source code repositories for the fundamental Swift components are hosted on GitHub at https://github.com/apple/swift. The following diagram shows the main components in open source Swift:
The license for the open source Swift projects is Apache 2.0 with a runtime library exception (https://github.com/apple/swift/blob/master/LICENSE.txt) .The runtime library exception clause in such a license allows you to compile the code into the binary product and distribute it.
The Swift compiler translates Swift source code into efficient machine code in an executable way. When parsing the source code, the Swift compiler will perform full type-checking and generate an intermediate language called the Swift Intermediate Language (SIL) for further code analysis and optimization. The intermediate code will then be reduced to Low Level Virtual Machine Intermediate Representation (LLVM IR) (http://llvm.org/) for the LLVM to turn that into machine code:
The standard library provides basic language and type system support. The core of the standard library includes the definitions of fundamental data types, collections, protocols, algorithm, and low-level primitives. There is also the language support runtime, which is layered between the compiler and the core of the standard library. This runtime handles the dynamic features of Swift, such as typecasting, generics, reflection, and memory management.
The foundation framework comprises features outside of the language and runtime that are common to all applications. The base layer of functionality provided in the foundation framework includes data storage and persistence, string handling, data formatting, date and time support, sorting and filtering, and networking. The design principle for the foundation framework is to keep the features in small sets of utility class, consistent across in convention, and with internationalization and localization support. As such, the foundation framework is highly portable for cross-platform support. There are two foundation frameworks: Objective-C and the open source Swift foundation.
The libdispatch is the wrapper for Grand Central Dispatch (GCD), the concurrency library used across all Swift platforms to provide support for concurrent code execution in multicore processors. GCD uses a dispatch queue to achieve the goal of executing tasks in parallel. Each queue is a block of code (task) that can be executed synchronously or asynchronously on the main thread or worker thread. Tasks submitted to dispatch queues are executed efficiently on a pool of threads managed by the system. Submitted tasks are executed serially by default, but several tasks can be configured to run concurrently when submitted to the dispatch queue.
The XCTest library is a common framework for writing unit tests in Swift. Usually, we just have to write the unit tests once and they can be executed across different platforms without rewriting. Each test is organized into an XCTestCase subclass with many different test methods. Each method shall be started with a prefix "test". We can run the tests from a Terminal on Linux or macOS. For Linux, an extra Linux main file with an array containing all available tests is needed. For macOS, XCode CLI tools to execute the tests are required. The XCTest framework is also well integrated into the workflow in XCode. We can use the scheme editor to specify which targets, classes, and methods to include a test, and use the XCode test navigator to run tests and view the results.
We use the Swift Package Manager (SPM) to manage the distribution of Swift projects. The Swift package manager integrates the package dependencies into the Swift build system, automating the downloading, compiling, and linking the other packages that are required in a Swift project. In a typical Swift project, the source code is organized into packages. We use the Swift package manager to set up target executable modules in a project and specify each executable's dependent modules. An executable is a Swift program that can be run by the host's platform. For example, we build one executable module for product release and another executable module for testing.
In open source Swift, the LLDB debugger is both a full-featured debugger for Swift and a read-eval-print-loop (REPL) tool for the language. The LLDB debugger is tightly coupled to the Swift compiler itself, in order for it to inspect Swift types accurately and evaluate expressions correctly. REPL takes advantage of the robust debugging features such as breakpoint settings, interactive context during failures, evaluating expressions, reporting, and formatting results at breakpoints.
CommonMark is the built-in Markdown syntax for documenting source code in open source Swift. Markdown is a plain text format for writing structured documents using very straightforward formatting conventions. Open source Swift adopts CommonMark as the implementation of a strongly defined, unambiguous, and highly compatible specification of Markdown.
Swift has been used extensively for client-side development in iOS, macOS, tvOS, and watchOS. Since the open source developer community brought Swift to the Linux platforms and made Swift a cross-platform programming language, it makes sense for developers to use Swift for server-side development as well.
Client developers that are already skillful with the Swift language and are accustomed to the tools and libraries used in Swift projects, will find the transition to server-side development straightforward. They can enjoy the same benefits offered by Swift in server-side projects: type-safety, ease of programming, and compiled performance. By using Swift in both client- and server-side development, developers are expected to be more productive and more skillful.
Of course, the client developers are required to learn some new server-side skills. The workflow on the client side is very different from that of server-side development. On the client side, developers often work to enhance user interfaces, build data models and develop application logic that works with remote cloud services. For server-side development, they need to be able to implement and test network requests, add logic to handle the requests, and route the requests to other backend modules to handle them.
As developers gain expertise in writing both server and client code, they will share code between the server and a client's modules, and optimize the code for both client and server-side development.
It is worth mentioning SwiftNIO here, together with other Swift technologies. Apple's SwiftNIO is an open source server-side kernel that provides low-level networking support to the high-level event-driven network application framework. Even though SwiftNIO is not part of open source Swift, this server-side kernel is the fundamental building block for Swift server-side frameworks such as Vapor 3.0. Support for SwiftNIO was also added to Kitura 2.5 in August 2018.
SwiftNIO targets high-performance protocol servers and clients with Netty-like event loops and asynchronous non-blocking calls. The rationale for SwiftNIO is that using the thread-per-connection model of concurrency for low-utilization connections in any server is highly inefficient. SwiftNIO uses the non-blocking I/O model, so we do not need to wait for data to be sent from the network or received from it. The kernel will notify us when an I/O operation is complete.
Under the hood of SwiftNIO, the event processing for managing the execution of work items is conceptualized into EventLoop, which is similar to a dispatch queue in Swift. There are usually a few event loops per CPU core. Event loops run for the entire lifetime of the application, dispatching events to all the objects they own in a SwiftNIO application. Event loops are grouped into an EventLoopGroup. When an EventLoopGroup receives tasks, it will distribute work around the event loops while ensuring thread safety in doing so.
We usually ask EventLoop to schedule work but the work itself will be done by ChannelHandlers in a Channel. Each file descriptor (socket, file, or pipe) in SwiftNIO is associated with a Channel, which performs operations on top of it. The Channel uses ChannelHandler to process each work item. ChannelHandler can handle either inbound or outbound data traffic or both. A sequence of ChannelHandler objects forms a ChannelPipeline so the data in a channel can be transformed as it passes through each ChannelHandler object in the pipeline.
There are several implementations of Channels in SwiftNIO, which are listed as follows:
ServerSocketChannel
: A channel for sockets that accepts connections like a server
SocketChannel
: A channel for TCP connections
DatagramChannel
: A channel for UDP sockets
EmbeddedChannel
: A channel for testing purposes
In a summary, SwiftNIO implements basic I/O primitives and protocols at low levels of abstraction. It is narrowly focused on providing a powerful building block for high-level networked applications.
There are many Swift web frameworks that aim to bring the benefits of Swift to server-side development. We will take a quick survey of several top Swift server-side frameworks now.
