David Chen | c4af828 | 2016-01-20 11:06:35 +0000 | [diff] [blame] | 1 | --- |
Damien Martin-Guillerez | 95a54b9 | 2016-07-28 12:47:11 +0000 | [diff] [blame] | 2 | layout: documentation |
| 3 | title: Tutorial - Build the Backend Server |
David Chen | c4af828 | 2016-01-20 11:06:35 +0000 | [diff] [blame] | 4 | --- |
Damien Martin-Guillerez | 95a54b9 | 2016-07-28 12:47:11 +0000 | [diff] [blame] | 5 | |
| 6 | # Tutorial - Build the Backend Server |
| 7 | |
| 8 | The backend server is a simple web application that runs on Google App Engine |
| 9 | and responds to incoming HTTP requests from the sample Android and iOS apps. |
| 10 | |
| 11 | Here, you'll do the following: |
| 12 | |
| 13 | * Review the source files for the app |
| 14 | * Update the `WORKSPACE` file |
| 15 | * Create the `appengine.BUILD` file |
| 16 | * Create a `BUILD` file |
| 17 | * Run the build |
| 18 | * Find the build outputs |
| 19 | * Deploy to a local development server |
| 20 | * Deploy to Google App Engine |
| 21 | |
| 22 | Bazel provides a set of [App Engine build rules](/docs/be/appengine.html) |
| 23 | written using the [Skylark](/docs/skylark/index.html) framework. You'll use |
| 24 | these in the steps below to build the application. |
| 25 | |
| 26 | ## Review the source files |
| 27 | |
| 28 | The source files for the backend server are located in `$WORKSPACE/backend/`. |
| 29 | |
| 30 | The key files and directories are: |
| 31 | |
| 32 | <table class="table table-condensed table-striped"> |
| 33 | <thead> |
| 34 | <tr> |
| 35 | <td>Name</td> |
| 36 | <td>Location</td> |
| 37 | </tr> |
| 38 | </thead> |
| 39 | <tbody> |
| 40 | <tr> |
| 41 | <td>Source file directory</td> |
| 42 | <td><code>src/main/java/com/google/bazel/example/app/</code></td> |
| 43 | </tr> |
| 44 | <tr> |
| 45 | <td>Web application metadata directory</td> |
| 46 | <td><code>webapp/WEB-INF/</code></td> |
| 47 | </tr> |
| 48 | </tbody> |
| 49 | </table> |
| 50 | |
| 51 | ## Update the WORKSPACE file |
| 52 | |
| 53 | As with the Android app, you must add references to |
| 54 | [external dependencies](http://bazel.io/docs/external.html) to your `WORKSPACE` |
| 55 | file. For the backend server, these are references to the App Engine SDK, |
| 56 | the Java Servlet SDK and other libraries needed to build the App Engine |
| 57 | applications. |
| 58 | |
| 59 | ### Add a new\_http\_archive rule |
| 60 | |
| 61 | When you built the Android app, you added a reference to the location on your |
| 62 | filesystem where you downloaded and installed the Android SDK. For the |
| 63 | backend server, however, you'll give Bazel instructions for downloading the |
| 64 | required App Engine SDK package from a remote server. This is optional. You |
| 65 | can also download and install the SDK manually on your filesystem and reference |
| 66 | it from that location as described in the |
| 67 | [App Engine rule documentation](/docs/be/appengine.html). |
| 68 | |
| 69 | Add the following to your `WORKSPACE` file: |
| 70 | |
| 71 | ```python |
| 72 | git_repository( |
| 73 | name = "io_bazel_rules_appengine", |
| 74 | remote = "https://github.com/bazelbuild/rules_appengine.git", |
| 75 | tag = "0.0.2", |
| 76 | ) |
| 77 | load("@io_bazel_rules_appengine//appengine:appengine.bzl", "appengine_repositories") |
| 78 | appengine_repositories() |
| 79 | ``` |
| 80 | |
| 81 | [`git_repository`](/docs/be/workspace.html#git_repository) downloads the |
| 82 | AppEngine rules from GitHub, then the next two lines use the |
| 83 | `appengine_repositories` function defined in these rules to download the |
| 84 | libraries and SDK needed to build AppEngine applications. |
| 85 | |
| 86 | Now, save and close the file. You can compare your `WORKSPACE` file to the |
| 87 | [completed example](https://github.com/bazelbuild/examples//blob/master/tutorial/WORKSPACE) |
| 88 | in the `master` branch of the GitHub repo. |
| 89 | |
| 90 | ## Create a BUILD file |
| 91 | |
| 92 | Now that you have set up the external dependencies, you can go ahead and create |
| 93 | the `BUILD` file for the backend server, as you did previously for the sample |
| 94 | Android and iOS apps. |
| 95 | |
| 96 | Open your new `BUILD` file for editing: |
| 97 | |
| 98 | ```bash |
| 99 | $ vi $WORKSPACE/backend/BUILD |
| 100 | ``` |
| 101 | |
| 102 | ### Add a java_binary rule |
| 103 | |
| 104 | Add the following to your `BUILD` file: |
| 105 | |
| 106 | ```python |
| 107 | java_binary( |
| 108 | name = "app", |
| 109 | srcs = glob(["src/main/java/**/*.java"]), |
| 110 | main_class = "does.not.exist", |
| 111 | deps = [ |
| 112 | "@io_bazel_rules_appengine//appengine:javax.servlet.api", |
| 113 | ], |
| 114 | ) |
| 115 | ``` |
| 116 | |
| 117 | The [`java_binary`](/docs/be/java.html#java_binary) tells Bazel |
| 118 | how to build a Java `.jar` library for your application, plus a wrapper shell |
| 119 | script that launches the application code from the specified main class. Here, |
| 120 | we're using this rule instead of the |
| 121 | [`java_library`](/docs/be/java.html#java_library) because we need |
| 122 | the `.jar` file to contain all the dependencies required to build the final |
| 123 | App Engine `.war` file. For this reason, we specify a bogus class name |
| 124 | for the `main_class` attribute. |
| 125 | |
| 126 | ### Add an appengine_war rule |
| 127 | |
| 128 | Add the following to your `BUILD` file: |
| 129 | |
| 130 | ```python |
| 131 | load("@io_bazel_rules_appengine//appengine:appengine.bzl", "appengine_war") |
| 132 | |
| 133 | appengine_war( |
| 134 | name = "backend", |
| 135 | data = [":webapp"], |
| 136 | data_path = "/backend/webapp", |
| 137 | jars = [":app_deploy.jar"], |
| 138 | ) |
| 139 | |
| 140 | filegroup( |
| 141 | name = "webapp", |
| 142 | srcs = glob(["webapp/**/*"]), |
| 143 | ) |
| 144 | ``` |
| 145 | |
| 146 | The [`appengine_war`](/docs/be/appengine.html#appengine_war) |
| 147 | rule builds the final App Engine `war` file from the library `.jar` file and web |
| 148 | application metadata files in the `webapp` directory. |
| 149 | |
| 150 | Save and close the file. Again, the |
| 151 | [completed example](https://github.com/google/bazel-examples/blob/master/tutorial/backend/BUILD) |
| 152 | is in the `master` branch of the GitHub repo. |
| 153 | |
| 154 | ## Run the build |
| 155 | |
| 156 | Make sure that your current working directory is inside your Bazel workspace: |
| 157 | |
| 158 | ```bash |
| 159 | $ cd $WORKSPACE |
| 160 | ``` |
| 161 | |
| 162 | Now, enter the following to build the sample app: |
| 163 | |
| 164 | ```bash |
| 165 | $ bazel build //backend:backend |
| 166 | ``` |
| 167 | |
| 168 | Bazel now launches and builds the sample app. During the build process, its |
| 169 | output will appear similar to the following: |
| 170 | |
| 171 | ```bash |
| 172 | INFO: Found 1 target... |
| 173 | Target //backend:backend up-to-date: |
| 174 | bazel-bin/backend/backend.war |
| 175 | bazel-bin/backend/backend.deploy |
| 176 | bazel-bin/backend/backend |
| 177 | INFO: Elapsed time: 56.867s, Critical Path: 2.72s |
| 178 | ``` |
| 179 | |
| 180 | ## Find the build outputs |
| 181 | |
| 182 | The `.war` file and other outputs are located in the |
| 183 | `$WORKSPACE/bazel-bin/backend` directory. |
| 184 | |
| 185 | ## Deploy to a local development server |
| 186 | |
| 187 | The `appengine_war` rule generates an upload script that you can use to deploy |
| 188 | your backend server on Google App Engine. Here, you'll start a local App Engine |
| 189 | development server in your environment and deploy your application there. |
| 190 | |
| 191 | To deploy the application, enter the following: |
| 192 | |
| 193 | ```bash |
| 194 | $ bazel-bin/backend/backend --port=12345 |
| 195 | ``` |
| 196 | |
| 197 | Your application URL will be `http://localhost:12345` |
| 198 | |
| 199 | ## Deploy to Google App Engine |
| 200 | |
| 201 | You can also deploy the application to the live App Engine serving |
| 202 | environment on Google Cloud Platform. For this scenario, you must first create |
| 203 | a project in the |
| 204 | [Google Developers Console](https://console.developers.google.com). |
| 205 | |
| 206 | To deploy the application, enter the following: |
| 207 | |
| 208 | ```bash |
| 209 | $ $WORKSPACE/bazel-bin/backend/backend.deploy <project-id> |
| 210 | ``` |
| 211 | |
| 212 | The deployment script prompts you to authorize access to Google Cloud Platform. |
| 213 | After you have authorized access the first time, you can deploy the application |
| 214 | using the `bazel` command and the following rule target: |
| 215 | |
| 216 | ```bash |
| 217 | $ bazel run //backend:backend.deploy <project-id> |
| 218 | ``` |
| 219 | |
| 220 | Your application URL will be `http://<project-id>.appspot.com`. |
| 221 | |
| 222 | ## What's next |
| 223 | |
| 224 | Now let's [review](review.md) the tutorial steps. |