Google has always been at the forefront of cloud innovation, and with its introduction of Cloud Run, it has once again demonstrated its commitment to providing top-tier cloud solutions for developers. In this blog post, we'll delve deep into the wonders of Google Cloud Run: what it is, its benefits, and how to get started.
Google Cloud Run is a fully managed compute platform that enables you to run containerized applications without provisioning or managing servers. Cloud Run scales your application automatically based on demand, so you can focus on building great applications without worrying about the infrastructure.
There are many benefits to using Cloud Run, including:
- Serverless: Cloud Run takes care of all the infrastructure management for you, so you can focus on your code.
- Scalability: Cloud Run scales your application automatically based on demand, so you can handle unexpected spikes in traffic without any downtime.
- Portability: Cloud Run uses standard containers, so you can easily port your applications to and from Cloud Run.
- Pay as You Go: With Cloud Run, you only pay for the compute time you use. If your application isn't running, you aren't charged. This not only makes it cost-effective but also ensures that you're not overspending on idle resources.
- Developer Friendly: Cloud Run supports multiple programming languages, and with its integration with Cloud Build, developers can automatically build and deploy their applications directly from their source repositories.
Use cases for Cloud Run
Cloud Run is a good choice for a wide range of applications, including:
- Web applications: Cloud Run is a great way to run web applications, such as blogs, e-commerce sites, and content management systems.
- Microservices: Cloud Run is a good choice for running microservices architectures, where each service is independently scalable and deployable.
- Event-driven applications: Cloud Run can be used to build event-driven applications, such as real-time data processing and notification systems.
- Machine learning applications: Cloud Run can be used to run machine learning applications, such as image recognition and natural language processing models.
Click here for more information, how to install and other steps.
Example
Tools
Operating Systems: Kubuntu
IDE: VSCode Google Cloud Code
Programming Language: Go
Container Runtime: Docker
We will create a microservice with some endpoints called patient-svc, which will be part of a Hospital Management System
- Register new patient
- Update patient details
- Retrieve patient details
- Ctrl + P then type > Cloud Run: New Application.
- Select the option Cloud Run application.
- In this case select Go: Cloud Run.
- Select the directory to save the project with the name patient-svc.
- In the Cloud Code status bar, click the active project name.
main.go
package main
import (
"encoding/json"
"log"
"net/http"
"sync"
)
type Patient struct {
ID string `json:"id"`
Name string `json:"name"`
Address string `json:"address"`
}
var patients = make(map[string]Patient)
var mu sync.Mutex
func RegisterPatient(w http.ResponseWriter, r *http.Request) {
var p Patient
if err := json.NewDecoder(r.Body).Decode(&p); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
mu.Lock()
patients[p.ID] = p
mu.Unlock()
w.WriteHeader(http.StatusCreated)
json.NewEncoder(w).Encode(p)
}
func UpdatePatientDetails(w http.ResponseWriter, r *http.Request) {
var p Patient
if err := json.NewDecoder(r.Body).Decode(&p); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
mu.Lock()
if _, exists := patients[p.ID]; exists {
patients[p.ID] = p
} else {
http.Error(w, "Patient not found", http.StatusNotFound)
mu.Unlock()
return
}
mu.Unlock()
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(p)
}
func RetrievePatientDetails(w http.ResponseWriter, r *http.Request) {
id := r.URL.Query().Get("id")
if id == "" {
http.Error(w, "ID is required", http.StatusBadRequest)
return
}
mu.Lock()
p, exists := patients[id]
mu.Unlock()
if !exists {
http.Error(w, "Patient not found", http.StatusNotFound)
return
}
json.NewEncoder(w).Encode(p)
}
func main() {
http.HandleFunc("/register", RegisterPatient)
http.HandleFunc("/update", UpdatePatientDetails)
http.HandleFunc("/retrieve", RetrievePatientDetails)
port := "8080"
log.Printf("Server started on :%s", port)
log.Fatal(http.ListenAndServe(":"+port, nil))
}
main_test.go
func TestRegisterPatient(t *testing.T) {
// Create a new request with a JSON payload
reqBody := []byte(`{"id": "123", "name": "John Doe", "age": 35}`)
req, err := http.NewRequest("POST", "/register", bytes.NewBuffer(reqBody))
if err != nil {
t.Fatal(err)
}
// Set the request header content type to JSON
req.Header.Set("Content-Type", "application/json")
// Create a response recorder to record the response
rr := httptest.NewRecorder()
// Call the RegisterPatient function with the response recorder and request
handler := http.HandlerFunc(RegisterPatient)
handler.ServeHTTP(rr, req)
// Check the status code is 201 Created
if status := rr.Code; status != http.StatusCreated {
t.Errorf("handler returned wrong status code: got %v want %v", status, http.StatusCreated)
}
// Check the response body is what we expect
expected := `{"id":"123","name":"John Doe","age":35}`
if rr.Body.String() != expected {
t.Errorf("handler returned unexpected body: got %v want %v", rr.Body.String(), expected)
}
}
func TestUpdatePatientDetails(t *testing.T) {
// Create a new request with a JSON payload
reqBody := []byte(`{"id": "123", "name": "John Doe", "age": 36}`)
req, err := http.NewRequest("PUT", "/update", bytes.NewBuffer(reqBody))
if err != nil {
t.Fatal(err)
}
// Set the request header content type to JSON
req.Header.Set("Content-Type", "application/json")
// Create a response recorder to record the response
rr := httptest.NewRecorder()
// Call the UpdatePatientDetails function with the response recorder and request
handler := http.HandlerFunc(UpdatePatientDetails)
handler.ServeHTTP(rr, req)
// Check the status code is 200 OK
if status := rr.Code; status != http.StatusOK {
t.Errorf("handler returned wrong status code: got %v want %v", status, http.StatusOK)
}
// Check the response body is what we expect
expected := `{"id":"123","name":"John Doe","age":36}`
if rr.Body.String() != expected {
t.Errorf("handler returned unexpected body: got %v want %v", rr.Body.String(), expected)
}
}
Debug
- In the Cloud Code status bar, click the active project name.
- Select Debug on Cloud Run Emulator. If it is the first time a form will appear. This is how I have it configured.
- Debug View from the VSCode Code Editor
- Test the endpoints
sh $ curl -X POST -H "Content-Type: application/json" -d '{"id": "123", "name": "John Doe", "age": 35}' http://localhost:8080/register {"id":"123","name":"John Doe","address":""}
sh $ curl -X PUT -H "Content-Type: application/json" -d '{"id": "123", "name": "John Doe", "age": 36}' http://localhost:8080/update {"id":"123","name":"John Doe","address":""}
sh $ curl -X GET http://localhost:8080/retrieve?id=123 {"id":"123","name":"John Doe","address":""}
## Deploy Refer to this guide for specific details https://cloud.google.com/run/docs/deploying
I present some screenshots of the details of my deployment using the Google Cloud Console.
https://patient-svc-3v56nzrvtq-uc.a.run.app
curl -X POST -H "Content-Type: application/json" -d '{"id": "123", "name": "John Doe", "age": 35}' https://patient-svc-3v56nzrvtq-uc.a.run.app/register
{"id":"123","name":"John Doe","address":""}
Google Cloud Run provides developers with a robust, scalable, and cost-effective platform to deploy containerized applications without the hassle of server management. As organizations continue to look for solutions that allow them to move fast and adapt to changing needs, platforms like Cloud Run will only become more pivotal. So, whether you're a startup or a well-established business, it might just be the right time to explore what Google Cloud Run can offer you!
Top comments (0)