36,59 €
Design production-ready, testable, and maintainable RESTful web services for the modern web that scale easily
Key Features
Book Description
Building RESTful web services can be tough as there are countless standards and ways to develop API. In modern architectures such as microservices, RESTful APIs are common in communication, making idiomatic and scalable API development crucial. This book covers basic through to advanced API development concepts and supporting tools.
You'll start with an introduction to REST API development before moving on to building the essential blocks for working with Go. You'll explore routers, middleware, and available open source web development solutions in Go to create robust APIs, and understand the application and database layers to build RESTful web services. You'll learn various data formats like protocol buffers and JSON, and understand how to serve them over HTTP and gRPC. After covering advanced topics such as asynchronous API design and GraphQL for building scalable web services, you'll discover how microservices can benefit from REST. You'll also explore packaging artifacts in the form of containers and understand how to set up an ideal deployment ecosystem for web services. Finally, you'll cover the provisioning of infrastructure using infrastructure as code (IaC) and secure your REST API.
By the end of the book, you'll have intermediate knowledge of web service development and be able to apply the skills you've learned in a practical way.
What you will learn
Who this book is for
This book is for all the Go developers who are comfortable with the language and seeking to learn REST API development. Even senior engineers can enjoy this book, as it discusses many cutting-edge concepts, such as building microservices, developing API with GraphQL, using protocol buffers, asynchronous API design, and Infrastructure as a Code. Developers who are already familiar with REST concepts and stepping into the Go world from other platforms, such as Python and Ruby, can also benefit a lot.
Das E-Book können Sie in Legimi-Apps oder einer beliebigen App lesen, die das folgende Format unterstützen:
Seitenzahl: 428
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:Richa TripathiAcquisition Editor:Denim PintoContent Development Editor: Divya VijayanSenior Editor: Mohammed Yusuf ImaratwaleTechnical Editor:Praveen GauravCopy Editor: Safis EditingProject Coordinator:Kinjal BariProofreader: Safis EditingIndexer:Pratik ShirodkarProduction Designer:Jyoti Chauhan
First published: December 2017 Second edition: February 2020
Production reference: 1280220
Published by Packt Publishing Ltd. Livery Place 35 Livery Street Birmingham B3 2PB, UK.
ISBN 978-1-83864-357-7
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.
Naren Yellavula, known in the developer community as Naren Arya, started his programming career in a somewhat surprising manner. He ditched mechanical engineering in favor of computer science after watching The Matrix for the first time. With domain expertise in cloud telephony and e-commerce, Naren has a total of 6 years' professional experience and 10 years of programming experience. His articles on open source have been read over a million times worldwide.
Naren has spoken at the PyCon India conference on two occasions. He currently works as a software engineer, building microservices for Tradebyte Software GmbH (a Zalando enterprise). In his spare time, he travels to new places. He also loves reading – nonfiction most of the time, and Victorian and Russian fiction on occasion.
Vincent Smith has been a software engineer for 10 years, having worked in various fields from health and IT to machine learning and large-scale web scrapers. He has worked for both large Fortune 500 companies and start-ups alike and has honed his skills by taking the best of both worlds. While obtaining a degree in electrical engineering, he learned the foundations of writing good code through his Java courses. These basics helped spur his career in software development early in his professional life in order to provide support for his team. He fell in love with the process of teaching computers how to behave, which set him on the path he still walks today.
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 RESTful Web Services with Go Second Edition
Dedication
About Packt
Why subscribe?
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
Download the color images
Conventions used
Get in touch
Reviews
Getting Started with REST API Development
Technical requirements
Types of web services
The REST API
Characteristics of REST services
REST verbs and status codes
GET
Examples of path parameters
POST, PUT, and PATCH 
DELETE and OPTIONS
Cross-Origin Resource Sharing (CORS)
The rise of the REST API with SPAs
Old and new methods of data flow in SPA
Why use Go for REST API development?
Setting up the project and running the development server
Demystifying GOPATH 
Building our first service – finding the fastest mirror site from a list
Open API and Swagger
Installing Swagger UI
Summary
Handling Routing for our REST Services
Technical requirements 
Understanding Go's net/http package
ServeMux – a basic router in Go
Developing a UUID generation API using ServeMux
Adding multiple handlers using ServeMux
Understanding httprouter – a lightweight HTTP router
Installing httprouter
Building a simple static file server in minutes
Introducing gorilla/mux – a powerful HTTP router
Installing gorilla/mux
Fundamentals of gorilla/mux
Path-based matching
Query-based matching
Other notable features of gorilla/mux
SQL injection in URLs and ways to avoid them
Reader's challenge – an API for URL shortening
Summary 
Working with Middleware and RPC
Technical requirements
What is middleware? 
Creating a basic middleware
Multiple middleware and chaining
Painless middleware chaining with Alice
Using Gorilla handlers middleware for logging 
What is RPC?
Creating an RPC server
Creating an RPC client
JSON-RPC using Gorilla RPC
Summary
Simplifying RESTful Services with Popular Go Frameworks
Technical requirements 
Introducing go-restful – a REST API framework
SQLite3 basics and CRUD operations
Building a Metro Rail API with go-restful
Design specification
Creating database models
Building RESTful API with the Gin framework
Building a RESTful API with revel.go
Summary 
Working with MongoDB and Go to Create a REST API
Technical requirements 
Introduction to MongoDB
Installing MongoDB and using the shell
Working with the MongoDB shell
Introducing mongo-driver, an official MongoDB driver for Go
RESTful API with gorilla/mux and MongoDB
Boosting the querying performance with indexing
Designing MongoDB documents for a delivery logistics API
Summary
Working with Protocol Buffers and gRPC
Technical requirements 
Introduction to protocol buffers
Protocol buffer language
Scalar values
Enumerations and repeated fields
Nested fields
Compiling a protocol buffer with protoc
Introduction to gRPC
Bidirectional streaming with gRPC
Summary
Working with PostgreSQL, JSON, and Go
Technical requirements 
Discussing PostgreSQL installation options
Installing via Docker
Adding users and databases in PostgreSQL
Introducing pq, a pure PostgreSQL database driver for Go
Implementing a URL-shortening service using PostgreSQL and pq
Defining the Base62 algorithm
Exploring the JSONStore feature in PostgreSQL
Introducing GORM, a powerful ORM for Go
Implementing the logistics REST API
Summary
Building a REST API Client in Go
Technical requirements
Plan for building a REST API client
Basics for writing a command-line tool in Go
CLI – a package for building beautiful clients
Collecting command-line arguments in the CLI
Cobra, an advanced CLI library
grequests a REST API package for Go
API overview of grequests
Getting comfortable with the GitHub REST API
Creating a CLI tool as an API client for the GitHub REST API
Using Redis to cache the API data
Summary
Asynchronous API Design
Technical requirements
Understanding sync/async API requests
Fan-in/fan-out of services
Delaying API jobs with queuing
RabbitMQ, a powerful message queue
Communicating with RabbitMQ in Go
Long-running task design
Caching strategies for APIs
go-redis, a Go client for communicating with Redis
Job status cache with Redis
Event-driven API
Summary
GraphQL and Go
Technical requirements 
What is GraphQL?
Over-fetching and under-fetching problems in the REST API
GraphQL basics
Types and queries
Object-level types
Field-level types
Non-nullable types
Enumerations
Queries and mutations
Mutations and inputs
Creating GraphQL clients in Go
Creating GraphQL servers in Go
Summary
Scaling our REST API Using Microservices
Technical requirements
What are microservices?
Monoliths versus microservices
Introducing Go Micro, a package for building microservices
Understanding encryption
Building a microservice with Go Micro
Building an RPC client with Go Micro
Building event-driven microservices
Adding logging to microservices
Summary
Containerizing REST Services for Deployment
Technical requirements 
Installing the Nginx server
Installation on a bare machine
Installation via a Docker container
What is a reverse proxy server?
Important Nginx paths
Using server blocks
Deploying a Go service using Nginx
Load balancing with Nginx
Rate limiting our REST API
Securing our Nginx proxy server
Monitoring our Go API server with Supervisord
Installing Supervisord
Makefile and Docker Compose-based deployment
Summary
Deploying REST Services on Amazon Web Services
Technical requirements 
Basics for working with AWS 
Managed services for applications from AWS
Setting up an AWS account
IaC with Terraform
Deploying a service on EC2
Why is an API Gateway required?
Introducing Amazon API Gateway
Deploying our service behind Amazon API Gateway
Other API Gateways
Summary
Handling Authentication for our REST Services
Technical requirements 
How simple authentication works
A simple authentication example
Introducing Postman, a visual client for testing a REST API
Persisting client sessions with Redis
Introducing JWT and OAuth2
JWT format
Reserved claims
Private claims
Creating a JWT in Go
Reading a JWT in Go
JWT in an OAuth2.0 workflow
Authentication versus authorization
Exercise
Security aspects of an API
Summary
Other Books You May Enjoy
Leave a review - let other readers know what you think
My association with this book has been a memorable journey. Three years back, when Packt contacted me to write a book for them, I was not sure that would be something I would be able to achieve in the first place. But, with support from my family, friends, and a few great mentors at work, I have successfully made it. I always have a habit of explaining things, and I wanted to turn that into a more significant form – a book. That desire ended up evolving into a book calledBuilding RESTful Web Services with Go in 2017. Looking back, it was not a bad idea at all.
I am an open source blogger apart from my full-time software development job. What I write about is what I learn at work. Every month, I work on many features, fix many bugs, and review many merge requests. I convert all that experience into articles. This book is a valuable collection of many of those experiences. You could ask me what provoked me to write this book? It is the burning desire to share things I know. Software engineering is a hard skill, and it has always been a practical discipline, unlike academic studies. That drove me to writeHands-On RESTful Web Services with Go, which is a supercharged sequel to my first book.
In this age of information technology, products talk with each other using Application Programming Interfaces (APIs). In the last decade, the rise of a new generation of web languages, such as Python, JavaScript (Node.js), and Go, has shown a different approach to web development compared to traditional ones, such as ASP.NET and Java's Spring.In particular, the Go programming language hits the sweet spot of the enterprise versus prototype landscape. We can compare Go simultaneously to what "Python is to prototyping" and what "Java is to the enterprise." Some of the best open source tools, such as Docker, Terraform, and Kubernetes, are written in Go. Google uses it heavily for its internal services. You can see a list of Go-using companies at https://github.com/golang/go/wiki/GoUsers.
With less verbose code, strict type checking, and support for concurrency, Go is a better language to write modern web servers. An intermediate Go developer can benefit a lot by knowing how to create RESTful services using Go. This book is an attempt to make the reader comfortable with web services development. Remember, it is a hands-on guide.
Industry experts are suggesting that, shortly, Python may move further into the data science domain, which could create a vacuum in the web development domain. Go has all the qualifications to fill that space. The paradigm shift from monoliths to microservices, and the need for robust API interfaces, may place Go high above interpreted languages.
Even though this book is not a cookbook, it offers many tips and tricks throughout your journey as a reader. This book is for software developers and web developers who want to develop RESTful web services and APIs using Go. It will also assist Python and Node.js developers who are interested in learning web development with Go.
I hope you enjoy this book, and that it helps take your career to the next level!
This book is for any Go developers who are comfortable with the language and seeking to learn REST API development. Even senior engineers will enjoy this book, as it discusses many cutting-edge concepts, such as building microservices, developing APIs with GraphQL, using protocol buffers, asynchronous API design, and infrastructure as code.
Developers who are already familiar with REST concepts and stepping into the Go world from other platforms, such as Python and Ruby, will also benefit a lot from reading this book.
Chapter 1, Getting Started with REST API Development, discusses the fundamentals of REST architecture and verbs.
Chapter 2, Handling Routing for our REST Services, describes how to define basic routes and handler functions for a REST API.
Chapter 3, Working with Middleware and RPC, covers working with middleware handlers and basic RPC.
Chapter 4, Simplifying RESTful Services with Popular Go Frameworks, presents quick prototyping of a REST API with a few open source frameworks.
Chapter 5, Working with MongoDB and Go to Create a REST API, explains how to use MongoDB as a storage backend for a REST API.
Chapter 6, Working with Protocol Buffers and gRPC, shows how to use protocol buffers and gRPC over HTTP/JSON to obtain a performance boost.
Chapter 7, Working with PostgreSQL, JSON, and Go, explains how to use PostgreSQL as a storage backend and leverage JSON stores to create REST APIs.
Chapter 8, Building a REST API Client in Go, presents techniques for building client software and API testing tools.
Chapter 9, Asynchronous API Design, presents techniques for scaling APIs by leveraging asynchronous design patterns.
Chapter 10, GraphQL and Go, discusses a different API query language in contrast to REST.
Chapter 11, Scaling our REST API Using Microservices, covers building microservices using Go Micro.
Chapter 12, Containerizing REST Services for Deployment, shows how to prepare a containerized ecosystem for API deployment.
Chapter 13, Deploying REST Services on Amazon Web Services, shows how to deploy a containerized ecosystem to AWS Cloud using infrastructure as code.
Chapter 14, Handling Authentication for our REST Services, discusses securing an API with simple authentication and JSON Web Tokens (JWT).
For this book, you need a laptop/PC with Linux (Ubuntu 18.04), macOS X >=10.13, or Windows installed. We will use Go 1.13.x as the version of our compiler and will install many third-party packages, so a working internet connection is required.
We will also use Docker in the final chapters to explain the concepts of API Gateway. Docker's latest stable version is recommended. If Windows users have problems with the native Go installation or using CURL for any examples, use Docker Desktop for Windows and run an Ubuntu container to test your code samples; refer to https://www.docker.com/docker-windows for more details.
Before diving into the book, refresh your language basics at https://tour.golang.org/welcome/1.
Even though these are the basic requirements, we will guide you through the installations whenever required.
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-Restful-Web-services-with-Go. 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!
We also provide a PDF file that has color images of the screenshots/diagrams used in this book. You can download it here: https://static.packt-cdn.com/downloads/9781838643577_ColorImages.pdf.
There are a number of text conventions used throughout this book.
CodeInText: Indicates code words in text, database table names, folder names, filenames, file extensions, pathnames, dummy URLs, user input, and Twitter handles. Here is an example: "Name the preceding program basicHandler.go."
A block of code is set as follows:
{ "ID": 1, "DriverName": "Menaka",}
When we wish to draw your attention to a particular part of a code block, the relevant lines or items are set in bold:
{ "ID": 1, "
DriverName
": "
Menaka
",}
Any command-line input or output is written as follows:
>
go run customMux.go
Bold: Indicates a new term, an important word, or words that you see onscreen. For example, words in menus or dialog boxes appear in the text like this. Here is an example: "It returns a message saying Logged In successfully."
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.
A web service is a communication mechanism defined between various computer systems. Without web services, custom peer-to-peer communication becomes cumbersome and platform-specific. The web needs to understand and interpret a hundred different things in the form of protocols. If computer systems can align with the protocols that the web can understand easily, it is a great help.
A web service is a software system designed to support interoperable machine-to-machine interaction over a network, as defined by the World Wide Web Consortium (W3C) at https://www.w3.org/TR/ws-arch/.
Now, in simple words, a web service is a road between two endpoints where messages are transferred smoothly. The message transfer is usually one way. Two individual programmable entities can also communicate with each other through their own APIs. Two people communicate through language, two applications communicate through an Application Programming Interface (API).
The reader might be wondering; what is the importance of the API in the current digital world? The rise of the Internet of Things (IoT) made API usage heavier than before. Awareness of APIs is growing day by day, and there are hundreds of APIs that are being developed and documented all over the world every day. Notable major businesses are seeing the future in the API as a Service (AaS). A bright example in recent times is Amazon Web Services (AWS). AWS is a huge success in the cloud world. Developers write their own applications using the Representational State Transfer (REST) API provided by AWS and access it via Command-Line Interface (CLI).
A few more hidden use cases are from travel sites such as http://Booking.com and https://www.expedia.com/, which fetch real-time prices by calling the APIs of third-party gateways and data vendors. Web service usage is often charged these days by the amount of data requests.
In this chapter, we will focus on the following topics:
The different web services available
REST
architecture in detail
The rise of
Single-page applications
(
SPAs
) with REST
Setting up a Go project and running a development server
Building our first service for finding the fastest mirror site from a list of Debian servers hosted worldwide
The Open API specification and Swagger documentation
There are many types of web services that have evolved over time. Some of the more prominent ones are as follows:
Simple Object Access Protocol
(
SOAP
)
Universal Description
,
Discovery, and Integration
(
UDDI
)
Web Services Description Language
(
WSDL
)
Representational State Transfer
(
REST
)
Out of these, SOAP became popular in the early 2000s, when XML riding on a high wave. The XML data format is used by various distributed systems to communicate with each other.
A SOAP request usually consists of these three basic components:
The envelope
The header
The body
Just to perform an HTTP request and response cycle, we have to attach a lot of additional data in SOAP. A sample SOAP request to a fictional book server, www.example.org, looks like this:
POST /Books HTTP/1.1Host: www.example.orgContent-Type: application/soap+xml; charset=utf-8Content-Length: 299SOAPAction: "https://www.w3.org/2003/05/soap-envelope"<?xml version="1.0"?><soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:m="https://www.example.org"> <soap:Header> </soap:Header> <soap:Body> <m:GetBook> <m:BookName>Alice in the wonderland</m:BookName> </m:GetBook> </soap:Body></soap:Envelope>
This is a standard example of a SOAP request for getting book data. If we observe carefully, it is in XML format, with special tags specifying the envelope and body. Since XML works by defining a lot of namespaces, the response gets bulky.
The main drawback of SOAP is that it is too complex for implementing web services and is a heavyweight framework. A SOAP HTTP request can get very bulky and can cause bandwidth wastage. The experts looked for a simple alternative, and in came REST. In the next section, we will briefly discuss REST.
The name Representational state transfer (REST) was coined by Roy Fielding from the University of California. It is a very simplified and lightweight web service compared to SOAP. Performance, scalability, simplicity, portability, and flexibility are the main principles behind the REST design.
The REST API allows different systems to communicate and send/receive data in a very simple way. Each and every REST API call has a relation between an HTTP verb and the URL. The resources in the database in an application can be mapped with an API endpoint in the REST architecture.
When you are using a mobile app on your phone, your phone might be talking to many cloud services to retrieve, update, or delete your data. REST services have a huge impact on our daily lives.
REST is a stateless, cacheable, and simple architecture that is not a protocol, but a pattern. This pattern allows different endpoints to communicate with each other over HTTP.
These are the main properties that make REST simple and unique compared to its predecessors:
Client-server based architecture
: This architecture is most essential for the modern web to communicate over HTTP. A single client-server may look naive initially, but many hybrid architectures are evolving. We will discuss more of these shortly.
Stateless
: This is the most important characteristic of a REST service. A REST HTTP request consists of all the data needed by the server to understand and return the response. Once a request is served, the server doesn't remember whether the request arrived after a while. So, the operation will be a stateless one.
Cacheable
: In order to scale an application well, we need to cache certain responses. REST services can be cached for better throughput.
Representation of resources
: The REST API provides the uniform interface to talk to. It uses a
Uniform Resource Identifier
(
URI
) to map the resources (data). It also has the advantage of requesting a specific data
Implementation freedom
: REST is just a mechanism to define your web services. It is an architectural style that can be implemented in multiple ways. Because of this flexibility, you can create REST services in the way you wish to. As long as it follows the principles of REST, you have the freedom to choose the platform or technology for your server.
We have seen the types of web services and understood what is REST API. We also looked at the characteristics that make REST services unique. In the next section, we will take a look at REST verbs and status code and cover a few examples of path parameters.
REST verbs specify an action to be performed on a specific resource or a collection of resources. When a request is made by the client, it should send the following information in the HTTP request:
The REST verb
Header information
The body (optional)
As we mentioned previously, REST uses the URI to decode the resource to be handled. There are quite a few REST verbs available, but six of them are used particularly frequently. They are presented, along with their expected actions, in the following table:
REST Verb
Action
GET
Fetches a record or set of resources from the server
OPTIONS
Fetches all available REST operations
POST
Creates
a resource or
a new set of resources
PUT
Updates or replaces the given record
PATCH
Modifies the given record
DELETE
Deletes the given resource
The status of these operations can be known from HTTP status codes. Whenever a client initiates a REST operation, since REST is stateless, the client should know a way to find out whether the operation was successful or not. For that reason, HTTP responses have a status code. REST defines a few standard status code types for a given operation. This means a REST API should strictly follow the following rules to achieve stable results in client-server communication. There are three important ranges available based on the types of error. See the following table for error ranges:
Status Code Type
Number Range
Action
Success
200 - 226
The 2xx family is used for successful responses.
Error
400 - 499 (client), 500 - 599 (server)
The 4xx family is used for indicating client errors. The 5xx is for server failures to process the request.
Redirect
300 - 308
The 3xx family is for URL redirection.
The detail of what each status code does is very precisely defined, and the overall count of codes increases every year. We mention the important ones in the upcoming section.
All requests to REST services have the following format. It consists of the host and the API endpoint. The API endpoint is the URL path that is predefined by the server. It can also include optional query parameters.
Let's look at all the verbs in more detail. The REST API design starts with the defining of operations and API endpoints. Before implementing the API, the design document should list all the endpoints for the given resources.
In the following section, we carefully observe the REST API endpoints using PayPal's REST API as a use case.
A GET method fetches the given resource from the server. To specify a resource, GET uses a few types of URI queries:
Query parameters
Path-based parameters
In case you didn't know, most of your browsing of the web is done by performing a GET request to the server. For example, if you type www.google.com, you are actually making a GET request to fetch the search page. Here, your browser is the client and Google's web server is the backend implementer of web services. A successful GET operation returns a 200 status code.
Everyone knows PayPal. PayPal creates billing agreements with companies. If you register with PayPal for a payment system, they provide you with a REST API for all your billing needs. The sample GET request for getting the information of a billing agreement looks like this: /v1/payments/billing-agreements/agreement_id.
Here, the resource query is with the path parameter. When the server sees this line, it interprets it as I got an HTTP request with a need foragreement_idfrom the billing agreements. Then it searches through the database, goes to the billing-agreements table, and finds an agreement with the given agreement_id. If that resource exists, it sends back a copy of the details in response (200 OK), or else it sends a response saying, "resource not found" (404).
Using GET, you can also query a list of resources, instead of a single one as in the preceding example. PayPal's API for getting billing transactions related to an agreement can be fetched with /v1/payments/billing-agreements/transactions. This line fetches all transactions that occurred on that billing agreement. In both instances, the data is retrieved in the form of a JSON response. The response format should be designed beforehand so that the client can consume it in the agreement.
Examples of query parameters are as follows:
Query parameters are intended to add detailed information to identify a resource from the server. For example, imagine a sample fictitious API. Let's assume this API is created for fetching, creating, and updating the details of the book. A query parameter based
GET
request will be in this format:
/v1/books/?category=fiction&publish_date=2017
The preceding URI has a couple of query parameters. The URI is requesting a book from the
books
resource that satisfies the following conditions:
It should be a fiction book
The book should have been published in the year 2017
Get all the fiction books that are released in the year 2017 is the question the client is posing to the server.
Path vs Query parameters—When to use them? It is a common rule of thumb that Query parameters are used to fetch multiple resources based on the Query parameters. If a client needs a single resource with exact URI information, it can use Path parameters to specify the resource. For example, a user dashboard can be requested with Path parameters, and fetch data on filtering can be modeled with Query parameters.
The POST method is used to create a resource on the server. In the previous books API, this operation creates a new book with the given details. A successful POST operation returns a 2xx status code. The POST request can update multiple resources: /v1/books.
The POST request can have a JSON body like the following:
{"name" : "Lord of the rings", "year": 1954, "author" : "
J. R. R. Tolkien
"}
This actually creates a new book in the database. An ID is assigned to this record so that when we GET the resource, the URL is created. So, POST should be done only once, in the beginning. In fact, Lord of the Rings was published in 1955. So, we entered the published date incorrectly. In order to update the resource, let's use the PUT request.
The PUT method is similar to POST. It is used to replace the resource that already exists. The main difference is that PUT is an idempotent operation. A POST call creates two instances with the same data. But PUT updates a single resource that already exists:
/v1/books/1256
PUT does this using a body containing JSON syntax, as follows:
{"name" : "Lord of the rings", "year": 1955, "author" : "J. R. R. Tolkien"}
1256 is the ID of the book. It updates the preceding book with year:1955. Did you observe the drawback of PUT? It actually replaced the entire old record with the new one. We needed to change a single column. But PUT replaced the whole record. That is bad. For this reason, the PATCH request was introduced.
The PATCH method is similar to PUT, except it won't replace the whole record. PATCH, as the name suggests, patches the column that is being modified. Let's update the book 1256 with a new column called ISBN:
/v1/books/1256
Let's use put the following JSON in the body:
{"isbn" : "0618640150"}
It tells the server, "search for the book with ID1256. Then add/modify this column with the given value."
The DELETE API method is used to delete a resource from the database. It is similar to PUT but without a body. It just needs an ID of the resource to be deleted. Once a resource gets deleted, subsequent GET requests return a 404 not found status.
The OPTIONS API method is the most underrated in API development. Given the resource, this method tries to find all possible methods (GET, POST, and so on) defined on the server. It is like looking at the menu card at a restaurant and then ordering an item that is available (whereas if you randomly order a dish, the waiter will tell you it is not available). It is best practice to implement the OPTIONS method on the server. From the client, make sure OPTIONS is called first, and if the method is available, then proceed with it.
The most important application of this OPTIONS method is Cross-Origin Resource Sharing (CORS). Initially, browser security prevented the client from making cross-origin requests. It means a site loaded with the www.foo.comURL can only make API calls to that host. If the client code needs to request files or data from www.bar.com, then the second server, bar.com, should have a mechanism to recognize foo.com to get its resources.
The following is the diagram depicting the CORS process:
Let's examine the steps followed in the preceding CORS diagram:
foo.com
requests the
OPTIONS
method on
bar.com
bar.com
sends a header like
Access-Control-Allow-Origin: http://foo.com
in response to the client
Next,
foo.com
can access the resources on
bar.com
without any restrictions that call any
REST
method
If bar.com feels like supplying resources to any host after one initial request, it can set the access control to *.
In the next section, we see why the REST API plays such a major role in the next generation of web services. SPAs made it possible to leverage APIs for all purposes, including the UI, clients, and so on.
Let's try to understand why SPAs are already standards of today's web. Instead of building a UI in the traditional way (that is, requesting rendered web pages), SPA designs allow developers to write code in a totally different way. There are many Model-View-Controller (MVC) frameworks, including Angular, React, Vue.js, and so on, for developing web UIs rapidly, but the essence of each of them is pretty simple. All MVC frameworks help us to implement one design pattern. That design pattern is no requesting of web pages, only REST API usage.
Modern frontend web development has advanced a lot in the last decade (2010-2020). In order to exploit the features of the MVC architecture, we have to consider the frontend as a separate entity that talks to the backend only using the REST API (preferably using JSON data).
In the traditional flow of serving requests, the order looks like this:
The client requests a web page from the server
The server authenticates and returns a rendered response
Every rendered response is in HTML with embedded data
With SPAs, however, the flow is quite different:
Request the HTML templates with the browser in one single go
Then, query the JSON REST API to fill a model (the data object)
Adjust the UI according to the data in the model (in JSON)
From the browser, push back the changes to the server via an API call
In this way, communication happens only in the form of the REST API. The client takes care of logically representing the data. This causes systems to move from Response-Oriented Architecture (ROA) to Service-Oriented Architecture (SOA). Take a look at the following diagram:
SPAs reduce bandwidth usage and improve site performance. SPAs are a major boost for API-centric server development because now a server can satisfy requirements for both browser and API clients.
REST services are trivial in the modern web. SOA (which we discuss in more detail later) created an activity space for REST services to take web development to the next level. Go is a programming language from the house of Google for solving the bigger problems they have. It has been over ten years since its first appearance. It matured along the way with the developer community jumping in and creating huge-scale systems in it.
We could choose Python or JavaScript (Node.js) for our REST API development, but the main advantage of Go lies in its speed and compile-time error detection. Go has been proven to be faster than dynamic programming languages in terms of computational performance according to various benchmarks. These are the three reasons why a company should write their next API in Go:
To scale your API for a wider audience
To enable your developers to build robust systems
To start simple and go big
As we progress through this book, we learn how to build efficient REST services in Go.
This is a building series book. It assumes you already know the basics of Go. If not, no worries. You can get a jump-start and learn the basics quickly from Go's official site at https://golang.org/. Writing a simple standalone program with Go is straightforward. But for big projects, we have to set up a clean project layout. For that reason, as a Go developer, you should know how Go projects are laid out and the best practices to keep your code clean.
Make sure you have done the following things before proceeding:
Install the Go compiler on your machine
Set the
GOROOT
and
GOPATH
environment variables
There are many online references from which you can get to know the preceding details. Depending on your machine type (Windows, Linux, or Mac OS X ), set up a working Go compiler. We will see more details about GOPATH in the following section.
GOPATH is nothing but the current appointed workspace on your machine. It is an environment variable that tells the Go compiler where your source code, binaries, and packages are placed.
The programmers coming from a Python background may be familiar with the Virtualenv tool for creating multiple projects (with different Python interpreter versions) at the same time. But at a given time, you can activate the environment for the project that you wish to work on and develop your project. Similarly, you can have any number of Go projects on your machine. While developing, set the GOPATH to one of your projects. The Go compiler now activates that project.
It is a common practice to create a project under the home directory and set the GOPATH environment variable as follows:
mkdir /home/user/workspace
export GOPATH=/home/user/workspace
Now, we install external packages like this:
go get -u -v github.com/gorilla/mux
Go copies a project called mux from GitHub into the currently activated project workspace.
A typical Go project, hello, should reside in the src directory in GOPATH, as mentioned on the official Go website:
Let's understand this structure before digging further:
bin
: Stores the binary of our project; a shippable binary that can be run directly
pkg
: Contains the package objects; a compiled program that supplies package methods
src
: The place for your project source code, tests, and user packages
In Go, all the packages imported into the main program have an identical structure, github.com/user/project. But who creates all these directories? Should the developer do that? Yes. It is the developer's responsibility to create directories for their project. It means they only create the src/github.com/user/hello directory.
When a developer runs the install command, the bin and package directories are created if they did not exist before. .bin consists of the binary of our project source code and .pkg consists of all internal and external packages we use in our Go programs:
go install github.com/user/project
Let's build a small service to brush up on our Go language skills. Operating systems such as Debian and Ubuntu host their release images on multiple FTP servers. These are called mirrors. Mirrors are helpful in serving an OS image from the closest point to a client. Let's build a service that finds the fastest mirror from a list of mirrors.