2
votes

Environment
I'm running AppEngine Cloud Endpoints with a Bootstrap JavaScript UI and a Google SQL Datastore.

Problem
When the Javascript calls gapi.client.load it gets a 404. The API Explorer works and the JavaScript works when run locally... It's just when trying to load the API via JavaScript that I get the failure.

Here's the error as it appears in Chrome:

GET https://MyAppID.appspot.com/_ah/api/discovery/v1/apis/myAP…%2Cversion%2CrootUrl%2CservicePath%2Cresources%2Cparameters%2Cmethods&pp=0 404       ()
zu @ cb=gapi.loaded_0:83
n @ cb=gapi.loaded_0:83C
u @ cb=gapi.loaded_0:83
(anonymous function) @ cb=gapi.loaded_0:84
g @ cb=gapi.loaded_0:55
c @ cb=gapi.loaded_0:46

It's then followed by another exception of "Cannot read property" because it can't find the method within the API that it didn't load.

Code

The code for my index.html page:

        function init() 
        {

            apisToLoad = 2;

            var callback = function() 
            {
                if (--apisToLoad == 0) 
                {
                      signin(true, userAuthed);
                   }
            }

            gapi.client.load('oauth2', 'v2', callback);
            //LOCALCHANGE (SWITCH BETWEEN LOCAL AND NOT)
            gapi.client.load('myAPI', 'v1', callback, 'https://MyAppId.appspot.com/_ah/api');
            //gapi.client.load('myAPI', 'v1', callback, 'http://localhost:8080/_ah/api');

        }

I think that's right, so I'm also going to include my appengine.xml:

<?xml version="1.0" encoding="utf-8"?>
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
<application>MyAppID</application>
<version>1</version>
<threadsafe>true</threadsafe>
<use-google-connector-j>true</use-google-connector-j>

<system-properties>
    <property name="java.util.logging.config.file" value="WEB-INF/logging.properties"/>
</system-properties>
</appengine-web-app>

and my web.xml:

<?xml version="1.0" encoding="utf-8" standalone="no"?><web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.5" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<servlet>
    <servlet-name>SystemServiceServlet</servlet-name>
    <servlet-class>com.google.api.server.spi.SystemServiceServlet</servlet-class>
    <init-param>
        <param-name>services</param-name>
        <param-value>com.lthoi.myAPI</param-value>
    </init-param>
</servlet>
<servlet-mapping>
    <servlet-name>SystemServiceServlet</servlet-name>
    <url-pattern>/_ah/spi/*</url-pattern>
</servlet-mapping>
<welcome-file-list>
    <welcome-file>index.html</welcome-file>
</welcome-file-list>
</web-app>

If anyone can think of anywhere else that the error could be, I'd be happy to paste other files.

3
Check your app logs for requests to /_ah/spi/BackendService.getApiConfig or /_ah/spi/BackendService.logMessages. If there are errors you need to fix them. - saiyr

3 Answers

0
votes

I'm having the same problem as u. It seems that google has a glitch with webapp endpoints that has caused this problem for quite some time now...

A link to previous posts about it: https://github.com/google/google-api-javascript-client/issues/147

(sry for putting post as answer, not comment, just created an account)

0
votes

So, the problem here was one of capitalization unfortunately. I had the right URL but tried to load 'myAPI' instead of 'MyAPI' as I had written it in MyAPI.java. Note that it's the value in the annotation and not the class name that matters in this case. Hopefully this finds anyone else who is as dumb as I am!

0
votes

The gapi.client.load queries discovery to get method information on an API (see the discovery part on the url that gives you 404). Currently discovery is not supported in cloud endpoints.

To work around, you can try to call the API directly (actually I'm not entirely sure whether this will work). e.g.

gapi.client.request({
  // Use your own service address, URI path, and query parameters.
  'root': 'https://your-domain.appspot.com',
  'path': '_ah/api/foo/bar', // use your own service path
  'params': {
    "foo": "bar"
  }
}).then(
  function(resp) {
    console.log(resp);
  },
  function(err) {
    console.log(err);
});

Hope this helps.

(Note that the CORS feature in the previous edit of this reply is experimental, undocumented, and unsupported but was used in this answer for debugging purposes. The line to enable CORS has been removed.)