In previous chapters, you developed three separate Cloud Run services that collectively constitute the backend for the Skills Mapper application. While the benefit of this arrangement is that each service can be individually maintained and scaled, it has led to a somewhat fragmented system. Navigating this structure currently requires an understanding of which functionality is provided by each distinct service. To recap, these three services are:
Skill service
This service offers suggestions of skills that can be added to the fact service.
Fact service
This is responsible for maintaining the facts necessary for constructing a profile.
Profile service
This updates user profiles as the associated facts evolve.
One significant challenge that needs to be addressed is unauthenticated invocation. Currently, these Cloud Run services expose their APIs to the internet without any authentication, which makes them susceptible to attacks.
To secure the system and streamline its operation, unifying these services under a single, secure API is the subject of this chapter. Additionally, you will deploy a user interface, providing users with a secure and consolidated point of access to the Skills Mapper application’s functionality.
Note
The code for this chapter is in the user-interface folder of the GitHub repository.
Requirements
Let’s look at the requirements for this final project. The user story for this functionality is shown in Figure 9-1.
Figure 9-1. Project 5 user story
Solution
This solution mainly introduces some of Google Cloud’s powerful networking services.
User Interface
So far, you have used Cloud Run to host backend services. You can also use it to host the UI using the same approach as you did for the backend services. You can use Cloud Build to create a container for the UI and deploy it to Cloud Run. However, as the UI is a static website, you will see there is an alternative approach using Cloud Storage and Cloud CDN that will be a little simpler and a lot more cost-effective.
OpenAPI
To bring together multiple services under a single API, you can define a common API using the OpenAPI specification. You can then use that as the configuration for a Google Cloud API Gateway.
Although OpenAPI is at version 3.1.0 at the time of writing this book, the API Gateway only supports version 2.0, better known as Swagger 2.0.
The great thing about using an OpenAPI specification is that only the specific endpoints explicitly defined will be exposed via the API Gateway. This has a security benefit; it means that any endpoints not defined in the specification will not be exposed.
For example, with the profile service, there is the endpoint that Google Pub/Sub uses to deliver events to the service. As this endpoint is not defined in the specification, it will not be exposed publicly via the API Gateway, meaning there is no way for an attacker to send a potentially damaging message to the service via that route.
API Gateway
Google API Gateway is a managed service that is intended to allow you to expose your APIs to the internet. It is a fully managed service that handles the scaling and load balancing of your APIs. It also provides several features such as authentication, rate limiting, and monitoring.
You will use the API Gateway to expose Skills Mapper’s API to the internet. The API Gateway will be configured from the OpenAPI 2.0 specification you create.
Global HTTP Load Balancer
In Chapter 11, the API Gateway and the UI will be fronted by a Global HTTP Load Balancer. This is a managed load balancer that is available in all regions. Again, it is a fully managed service. You will be able to provide a custom domain name and generate an SSL certificate to secure the connection.
Figure 9-2 includes a diagram of the solution.
Figure 9-2. Citadel design
Implementation
Once again, let’s roll up our sleeves and move onto the implementation.
Hosting the UI on Cloud Run
The user interface for Skills Mapper is built using HTML, the Materialize UI framework, and JavaScript. As a result, it is a static website.
You can use Cloud Build to create a container for it and deploy it to Cloud Run. However, there is a little configuration to do first. Since you are using Identity Platform for authentication, you need to configure the UI to use the correct client ID. This is done by creating a file called config.js directory.
You need to populate the file with the values of the project ID and the API Key from the Identity Platform configuration.