Remote API for Java
The Java SDK includes a library called Remote API that lets you transparently access App Engine services from any Java application. For example, you can use Remote API to access a production datastore from an app running on your local machine. You can also use Remote API to access the datastore of one App Engine app from a different App Engine app.
Configuring Remote API on the Server
The server component of Remote API is a Java servlet that is part of the App
Engine Java runtime. This servlet receives requests from the Remote API client,
dispatches them to the appropriate backend service, and then returns the result
of the service call to the client. To install the Remote API servlet, add the
following to your
web.xml
:
<servlet>
<display-name>Remote API Servlet</display-name>
<servlet-name>RemoteApiServlet</servlet-name>
<servlet-class>com.google.apphosting.utils.remoteapi.RemoteApiServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>RemoteApiServlet</servlet-name>
<url-pattern>/remote_api</url-pattern>
</servlet-mapping>
The servlet returns an error if there is no authenticated user or the authenticated user is not an admin of your application, so there is no need to configure any additional security. Once you've deployed your app with these settings, any app with the Remote API client installed can use its services. This includes Python clients that are using the Python Remote API.
Configuring Remote API on a Standalone Client
To configure the client component of Remote API for use inside a Java
application, add
${SDK_ROOT}/lib/impl/appengine-api.jar
and
${SDK_ROOT}/lib/appengine-remote-api.jar
to your classpath. Then, in your
code, configure and install Remote API:
import com.google.appengine.tools.remoteapi.RemoteApiInstaller;
import com.google.appengine.tools.remoteapi.RemoteApiOptions;
// ...
RemoteApiOptions options = new RemoteApiOptions()
.server("<i>your_app_id</i>.appspot.com", 443)
.credentials(username, password);
RemoteApiInstaller installer = new RemoteApiInstaller();
installer.install(options);
// ... all API calls executed remotely
installer.uninstall();
You can just as easily connect to an App Engine app running locally in the Development Server :
// Username and password don't matter
String username = "[email protected]";
String password = "";
RemoteApiOptions options = new RemoteApiOptions()
.server("localhost", 8888) // server name must equal "localhost"
.credentials(username, password);
Here's a complete Java application that, when run, prompts for the username and password of an admin of a running app and then inserts an Entity into the datastore of that app:
package remoteapiexample;
import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.tools.remoteapi.RemoteApiInstaller;
import com.google.appengine.tools.remoteapi.RemoteApiOptions;
import java.io.IOException;
public class RemoteApiExample {
public static void main(String[] args) throws IOException {
String username = System.console().readLine("username: ");
String password =
new String(System.console().readPassword("password: "));
RemoteApiOptions options = new RemoteApiOptions()
.server("<i>your_app_id</i>.appspot.com", 443)
.credentials(username, password);
RemoteApiInstaller installer = new RemoteApiInstaller();
installer.install(options);
try {
DatastoreService ds = DatastoreServiceFactory.getDatastoreService();
System.out.println("Key of new entity is " +
ds.put(new Entity("Hello Remote API!")));
} finally {
installer.uninstall();
}
}
}
Services that you access via Remote API have different performance characteristics than services you access directly. For more information about these differences, read Accessing the datastore remotely with remote_api . The article is Python-specific, but the concepts and gotchas apply to Java as well.
Configuring Remote API on an App Engine Client
You can also use Remote API to access the services of one App Engine application
from a different App Engine application. You need to add
${SDK_ROOT}/lib/appengine-remote-api.jar
to your
WEB-INF/lib
directory and
then, in your client App Engine app, configure and install Remote API just as
you did in your standalone Java client. Here's a class that accepts the
username and password of an admin of the target App Engine app, installs Remote
API with the provided credentials, inserts an Entity into the datastore of the
target app, and then uninstalls Remote API:
package remoteapiexample;
import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.tools.remoteapi.RemoteApiInstaller;
import com.google.appengine.tools.remoteapi.RemoteApiOptions;
import java.io.IOException;
class RemoteApiInsideAppEngineExample {
private final RemoteApiOptions options;
RemoteApiInsideAppEngineExample(String username, String password)
throws IOException {
// Authenticating with username and password is slow, so we'll do it
// once during construction and then store the credentials for reuse.
this.options = new RemoteApiOptions()
.server("<i>your_target_app_id</i>.appspot.com", 443)
.credentials(username, password);
RemoteApiInstaller installer = new RemoteApiInstaller();
installer.install(options);
try {
// Update the options with reusable credentials so we can skip
// authentication on subsequent calls.
options.reuseCredentials(username, installer.serializeCredentials());
} finally {
installer.uninstall();
}
}
void putInRemoteDatastore(Entity entity) throws IOException {
RemoteApiInstaller installer = new RemoteApiInstaller();
installer.install(options);
try {
DatastoreService ds = DatastoreServiceFactory.getDatastoreService();
System.out.println("Key of new entity is " + ds.put(entity));
} finally {
installer.uninstall();
}
}
}