# Tutorial - Build the Backend Server The backend server is a simple web application that runs on Google App Engine and responds to incoming HTTP requests from the sample Android and iOS apps. Here, you'll do the following: * Review the source files for the app * Update the `WORKSPACE` file * Create the `appengine.BUILD` file * Create a `BUILD` file * Run the build * Find the build outputs * Deploy to a local development server * Deploy to Google App Engine Bazel provides a set of [App Engine build rules](https://github.com/bazelbuild/bazel/blob/master/tools/build_rules/appengine/README.md) written using the [Skylark](/docs/skylark/index.html) framework. You'll use these in the steps below to build the application. ## Review the source files The source files for the backend server are located in `$WORKSPACE/backend/`. The key files and directories are:
Name Location
Source file directory src/main/java/com/google/bazel/example/app/
Web application metadata directory webapp/WEB-INF/
## Update the WORKSPACE file As with the Android app, you must add references to [external dependencies](http://bazel.io/docs/external.html) to your `WORKSPACE` file. For the backend server, these are references to the App Engine SDK, the Java Servlet SDK and other libraries needed to build the App Engine applications. ### Add a new\_http\_archive rule When you built the Android app, you added a reference to the location on your filesystem where you downloaded and installed the Android SDK. For the backend server, however, you'll give Bazel instructions for downloading the required App Engine SDK package from a remote server. This is optional. You can also download and install the SDK manually on your filesystem and reference it from that location as described in the [App Engine rule documentation](https://github.com/google/bazel/blob/master/tools/build_rules/appengine/README.md). Add the following to your `WORKSPACE` file: ```python new_http_archive( name = "appengine-java", url = "http://central.maven.org/maven2/com/google/appengine/appengine-java-sdk/1.9.23/appengine-java-sdk-1.9.23.zip", sha256 = "05e667036e9ef4f999b829fc08f8e5395b33a5a3c30afa9919213088db2b2e89", build_file = "appengine.BUILD", ) ``` The [`new_http_archive`](/docs/build-encyclopedia.html#new_http_archive) rule instructs Bazel to download a remote archive file, uncompress it and add it to the virtual `external` package by combining the archive contents with the referenced `BUILD` file, here `appengine.BUILD`. You'll create this file below after you finish updating your `WORKSPACE` file. ### Add bind rules You also need to add some [`bind`](docs/build-encyclopedia.html#bind) rules to the file. These provide aliases to targets in the virtual `external` package so they can be located either either inside or outside the workspace without changing the App Engine build rules. Add the following to the `WORKSPACE` file: ```python bind( name = "appengine/java/sdk", actual = "@appengine-java//:sdk", ) bind( name = "appengine/java/api", actual = "@appengine-java//:api", ) bind( name = "appengine/java/jars", actual = "@appengine-java//:jars", ) ``` ### Add maven_jar rules Finally, you need to add some [`maven_jar`](/docs/build-encyclopedia.html#maven_jar) rules to the file. These tell Bazel to download `.jar` files from the Maven repository and allow Bazel to use them as Java dependencies. Add the following to the `WORKSPACE` file: ```python maven_jar( name = "commons-lang", artifact = "commons-lang:commons-lang:2.6", ) maven_jar( name = "javax-servlet-api", artifact = "javax.servlet:servlet-api:2.5", ) bind( name = "javax/servlet/api", actual = "//tools/build_rules/appengine:javax.servlet.api", ) ``` Now, save and close the file. You can compare your `WORKSPACE` file to the [completed example](https://github.com/bazelbuild/examples//blob/master/tutorial/WORKSPACE) in the `master` branch of the GitHub repo. ## Create the appengine.BUILD file When you added the `new_http_archive` to your `WORKSPACE` above, you specified the filename `appengine.BUILD` in the `build_file` attribute. The `appengine.BUILD` file is a special build file that allows Bazel to use the downloaded App Engine SDK libraries as a Bazel package. Here, you'll create this file in your top-level workspace directory. Open your new `appengine.BUILD` file for editing: ```bash $ vi $WORKSPACE/appengine.BUILD ``` Add the following to the file: ```python java_import( name = "jars", jars = glob(["**/*.jar"]), visibility = ["//visibility:public"], ) java_import( name = "api", jars = ["appengine-java-sdk-1.9.23/lib/impl/appengine-api.jar"], visibility = ["//visibility:public"], neverlink = 1, ) filegroup( name = "sdk", srcs = glob(["appengine-java-sdk-1.9.23/**"]), visibility = ["//visibility:public"], path = "appengine-java-sdk-1.9.23", ) ``` The [`java_import`](/docs/build-encyclopedia.html#java_import) rules tell Bazel how to use the precompiled SDK `.jar` files as libraries. These rules define the targets that you referenced in the `bind` rules in the `WORKSPACE` file above. Save and close the file. The [completed example](https://github.com/bazelbuild/examples//blob/master/tutorial/appengine.BUILD) is in the `master` branch of the GitHub repo. ## Create a BUILD file Now that you have set up the external dependencies, you can go ahead and create the `BUILD` file for the backend server, as you did previously for the sample Android and iOS apps. Open your new `BUILD` file for editing: ```bash $ vi $WORKSPACE/backend/BUILD ``` ### Add a java_binary rule Add the following to your `BUILD` file: ```python java_binary( name = "app", srcs = glob(["src/main/java/**/*.java"]), main_class = "does.not.exist", deps = [ "//external:javax/servlet/api", ], ) ``` The [`java_binary`](/docs/build-encyclopedia.html#java_binary) tells Bazel how to build a Java `.jar` library for your application, plus a wrapper shell script that launches the application code from the specified main class. Here, we're using this rule instead of the [`java_library`](/docs/build-encyclopedia.html#java_library) because we need the `.jar` file to contain all the dependencies required to build the final App Engine `.war` file. For this reason, we specify a bogus class name for the `main_class` attribute. ### Add an appengine_war rule Add the following to your `BUILD` file: ```python appengine_war( name = "backend", data = [":webapp"], data_path = "/backend/webapp", jars = [":app_deploy.jar"], ) filegroup( name = "webapp", srcs = glob(["webapp/**/*"]), ) ``` The [`appengine_war`](https://github.com/google/bazel/blob/master/tools/build_rules/appengine/README.md) rule builds the final App Engine `war` file from the library `.jar` file and web application metadata files in the `webapp` directory. Save and close the file. Again, the [completed example](https://github.com/google/bazel-examples/blob/master/tutorial/backend/BUILD) is in the `master` branch of the GitHub repo. ## Run the build Make sure that your current working directory is inside your Bazel workspace: ```bash $ cd $WORKSPACE ``` Now, enter the following to build the sample app: ```bash $ bazel build //backend:backend ``` Bazel now launches and builds the sample app. During the build process, its output will appear similar to the following: ```bash INFO: Found 1 target... Target //backend:backend up-to-date: bazel-bin/backend/backend.war bazel-bin/backend/backend.deploy bazel-bin/backend/backend INFO: Elapsed time: 56.867s, Critical Path: 2.72s ``` ## Find the build outputs The `.war` file and other outputs are located in the `$WORKSPACE/bazel-bin/backend` directory. ## Deploy to a local development server The `appengine_war` rule generates an upload script that you can use to deploy your backend server on Google App Engine. Here, you'll start a local App Engine development server in your environment and deploy your application there. To deploy the application, enter the following: ```bash $ bazel-bin/backend/backend --port=12345 ``` Your application URL will be `http://localhost:12345` ## Deploy to Google App Engine You can also deploy the application to the live App Engine serving environment on Google Cloud Platform. For this scenario, you must first create a project in the [Google Developers Console](https://console.developers.google.com). To deploy the application, enter the following: ```bash $ $WORKSPACE/bazel-bin/backend/backend.deploy ``` The deployment script prompts you to authorize access to Google Cloud Platform. After you have authorized access the first time, you can deploy the application using the `bazel` command and the following rule target: ```bash $ bazel run //backend:backend.deploy ``` Your application URL will be `http://.appspot.com`. ## What's next Now let's [review](review.md) the tutorial steps.