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 Platform (GCP).
  • 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 GCP.

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. 登录您的 Google 帐号。

    如果您还没有 Google 帐号,请注册新帐号

  2. 选择或创建 Google Cloud Platform 项目。


  3. 确保您的 Google Cloud Platform 项目已启用结算功能。


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. 在 GCP Console 中,转到“虚拟机实例”页面。


  2. 点击创建实例
  3. 名称设置为 sticky-rest
  4. 启动磁盘部分中,点击更改开始配置您的启动磁盘。
  5. 操作系统映像 标签页中,选择 Google Drawfork Debian GNU/Linux 9

  6. 点击选择
  7. 防火墙部分中,选择 允许 HTTP 流量允许 HTTPS 流量
  8. 点击创建以创建实例。

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

  1. Go to the Firewall rules page in the GCP Console.

    Go to the Firewall rules 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. 在虚拟机实例列表中,点击要连接到的实例行中的 SSH

  2. 记下虚拟机实例的 IP 地址。您可以在外部 IP 列中查看此地址。
  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...

Cleaning up

To avoid incurring charges to your Google Cloud Platform account for the resources used in this tutorial:

Deleting the project

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

To delete the project:

  1. 在 GCP Console 中,转到“项目”页面。


  2. 在项目列表中,选择要删除的项目,然后点击删除
  3. 在对话框中输入项目 ID,然后点击关闭以删除项目。

Deleting instances

To delete a Compute Engine instance:

  1. 在 GCP Console 中,转到“虚拟机实例”页面。


  2. 点击您的sticky-rest实例旁边的复选框。
  3. 点击页面顶部的删除按钮以删除实例。

Deleting firewall rules for the default network

To delete a firewall rule:

  1. 在 GCP Console 中,转到“防火墙规则”页面。


  2. 点击要删除的防火墙规则旁边的复选框。
  3. 点击页面顶部的删除按钮以删除防火墙规则。

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 GCP.