Build a Mobile App Using Compute Engine and REST

Running your mobile backend on Compute Engine and using REST as the communication protocol between your mobile app and the backend server has several advantages:

  • It is the fastest way to move an existing service, running on an on-premises or virtual machine, to Google Cloud.
  • It gives you full control over your virtual machine and server configuration.
  • You can use third-party libraries.
  • You can configure an autoscaler to scale the number of virtual machines to meet demand.

The downside to running your service on Compute Engine is that you are responsible for maintaining and updating your server.

This tutorial walks you through building a sample mobile app called Stickynotes. This sample app uses REST to connect to a backend service running on Compute Engine.

The Stickynotes sample includes code for a frontend mobile app and a backend service, which work together in the following workflow:

  1. The mobile app allows you to enter a message into a text field.
  2. The app sends your message to a REST endpoint in the backend service.
  3. The backend service creates an image that contains the text message using the draw2d library.
  4. The backend service returns the image to the mobile app.
  5. The mobile app displays the image with your message embedded in it.

The client app is an iOS app, and the backend service is written in the Go programming language.


This tutorial shows how to:

  • Create an iOS mobile app that connects to a REST endpoint in the backend service.
  • Configure and run a REST backend service on Compute Engine.


This tutorial uses a Compute Engine instance, which is a billable component of Google Cloud.

Use the Pricing Calculator to generate a cost estimate based on your projected usage. New GCP users might be eligible for a free trial.

Before you begin

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. In the Google Cloud Console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  3. Make sure that billing is enabled for your Cloud project. Learn how to confirm that billing is enabled for your project.

Install the following software:

Clone the sample code

Run the following command to clone the sample code:

git clone

Then navigate to the /solutions/stickynoteapi/REST directory to find the sample code for this solution.

Run the server locally

In the /stickynoteapi/REST/Go directory, run the following command:


The command displays the following output:

1. Set gopath and search path
2. Get the server and client dependencies
3. Build the server and client
4. Stop any previously-running instances of the server
5. Start the server
6. Run the client
2016/03/02 11:34:48 OK: message.png
7. Open the image in message.png

The setup also runs a local client to test the server with the phrase "Remember the milk". The server generates a message.png file that contains the corresponding image.

Remember the milk.

To generate images based on your own messages using the command-line client, run the following command:

./client "This is a test..."

The /stickynoteapi/REST/Go/go/src/server/server.go file contains the code that runs the REST server. The main function defines a handler for the root-level directory and listens for traffic on port 8080.

func main() {
	http.HandleFunc("/stickynote", handler)
	http.ListenAndServe(":8080", nil)
	//http.ListenAndServeTLS(":443", "ssl.crt", "ssl.key", nil)

The server routes incoming requests to the handler function, which performs the following actions:

  1. Extracts the text message from the REST request.
  2. Uses the functions defined in sticky.go to build an image based on the text message.
  3. Returns the image to the client in a REST response.
func handler(w http.ResponseWriter, r *http.Request) {
	var sticky Sticky
	sticky.Message = r.FormValue("message")
	sticky.Centered = false
	stickyBytes, err := sticky.DrawPNG(512, 512)
	if err == nil {

Leave the local server running so you can use it to test the client app in the next section.

Run the iOS client with the local server

  1. In the stickynoteapi/REST/Objective-C/ directory, open stickynotes.xcodeproj in Xcode.
  2. Select Product > Run to build and start the client app.
  3. Enter a message in the text field and tap Return.

An image of a yellow sticky note with your message appears beneath the text field.

This is a test...

The client app sets the location of the backend service in the file StickyNotesViewController.m. For testing purposes, this is initially set to localhost, on port 8080.

static NSString * const kHostAddress = @"localhost:8080";

When you tap Return after entering your message in the text field, the app encodes the message into a query string and sends it to the server in a REST request. The app receives the REST response, extracts the generated image, and displays it in an image view. The following code shows the action that handles these tasks:

- (IBAction) textFieldDidEndEditing:(UITextField *)textField
  NSString *queryString = [NSString stringWithFormat:@"http://%@/stickynote?message=%@",
                           [textField.text urlencode]];
  NSURL *URL = [NSURL URLWithString:queryString];
  _request = [NSMutableURLRequest requestWithURL:URL];

  NSURLSession *session = [NSURLSession sharedSession];
  _task = [session dataTaskWithRequest:_request
           ^(NSData *data, NSURLResponse *response, NSError *error) {
             UIImage *image = [UIImage imageWithData:data];
             dispatch_async(dispatch_get_main_queue(), ^{
                              self.imageView.image = image;
  [_task resume];

Run the server on Compute Engine

To host the server on Compute Engine, create a compute instance:

  1. In the Cloud Console, go to the VM instances page.

    Go to VM instances

  2. Click Create instance.
  3. Set Name to sticky-rest.
  4. In the Boot disk section, click Change to begin configuring your boot disk.
  5. On the Public images tab, choose Google Drawfork Debian GNU/Linux 9.

  6. Click Select.
  7. In the Firewall section, select Allow HTTP traffic and Allow HTTPS traffic.
  8. Click Create to create the instance.

To allow client requests to the instance, create a firewall rule:

  1. Go to the Firewall page in the Cloud Console.

    Go to the Firewall page

  2. In the Create a firewall rule page, enter the following information:

    • Name: sticky-rest
    • Target tags: http-server
    • Source IP ranges:
    • Protocol and ports: tcp:8080
  3. Click Create.

To start the server on the instance, clone the server code and run the setup script:

  1. In the list of virtual machine instances, click SSH in the row of the instance that you want to connect to.

    SSH button next to instance name.

  2. Make a note of the IP address of your VM instance. You can see this address in the External IP column.
  3. Install Git on the instance:

    sudo apt update
    sudo apt install git
  4. Install the Go tools:

    sudo wget
    sudo tar -C /usr/local -xzf go1.10.linux-amd64.tar.gz
    export PATH="/usr/local/go/bin:${PATH}"
  5. Clone the Stickynotes server code:

    git clone
  6. Start the Stickynotes server on the instance. In the /solutions/stickynoteapi/REST/Go directory, run the following command:

    sh SETUP

To configure and run the client app:

  1. In Xcode, edit StickyNotesViewController.m to change localhost to the value of the External IP field of your Compute Engine instance noted in a previous step.

    // static NSString \* const kHostAddress = @"localhost:8080";
    static NSString \* const kHostAddress = @"[YOUR-INSTANCE-EXTERNAL-IP]:8080";
  2. Select File > Save to save your changes.

  3. Select Product > Run to build and start the client app.

  4. Enter a message in the text field and tap Return.

An image of a yellow sticky note with your message replaces the gray background.

Testing on remote server...

Clean up

To avoid incurring charges to your Google Cloud account for the resources used in this tutorial, either delete the project that contains the resources, or keep the project and delete the individual resources.

Deleting the project

The easiest way to eliminate billing is to delete the project that you created for the tutorial.

To delete the project:

  1. In the Cloud Console, go to the Manage resources page.

    Go to Manage resources

  2. In the project list, select the project that you want to delete, and then click Delete.
  3. In the dialog, type the project ID, and then click Shut down to delete the project.

Deleting instances

To delete a Compute Engine instance:

  1. In the Cloud Console, go to the VM instances page.

    Go to VM instances

  2. Select the checkbox for your sticky-rest instance.
  3. To delete the instance, click More actions, click Delete, and then follow the instructions.

Deleting firewall rules for the default network

To delete a firewall rule:

  1. In the Cloud Console, go to the Firewall page.

    Go to Firewall

  2. Select the checkbox for the firewall rule that you want to delete.
  3. To delete the firewall rule, click Delete.

What's next

This sample demonstrates the basics of how to connect a mobile app to code running on Compute Engine using REST. To extend this sample into a real app, consider adding the following enhancements:

  • Add a static external IP address to your server—by default, the external address associated with a Compute Engine instance is transient. In a production app, attach a static external IP address to your instance. For more information, see Configuring an Instance’s IP Address.

  • Use credentials to connect to an HTTPS server—ensure that your backend service can be called only by your mobile app by requiring your mobile app to use credentials to authenticate itself to the server. Protect the privacy of the data that your users send to the server, by using the encrypted HTTPS protocol instead of HTTP. To do this you could run a NGINX server as an SSL proxy on your instance or run your backend server in the App Engine flexible environment. For more information, see Securely Connecting to VM Instances.

  • Add load balancing and autoscaling—handle traffic spikes gracefully by setting up a load balancer and autoscaler to spin up extra instances when demand grows, and to route traffic evenly across those instances. For more information, see Setting up HTTP(s) Load Balancing and Autoscaling Groups of Instances.

  • Explore using the gRPC protocol instead of RESTgRPC is a framework that makes it possible for a mobile app to directly call methods on a backend service as if it was a local object. You can use gRPC to make your mobile app more bandwidth-efficient and to reduce latency between your app and backend service running on GCP. For an example of how to use gRPC in the Stickynotes sample, see Build a mobile app using Google Compute Engine and gRPC

  • Consider other hosting options for your backend service—Compute Engine offers the greatest degree of control over your virtual machine, but at the cost of you manually updating and managing your instance. For a discussion of other ways to host a mobile backend service on Cloud Platform, see Build mobile apps using Google Cloud.