0
votes

I have created a Cloud Endpoint through Android Studio as part of an Android project.

I am not intending to use this part of the Cloud Endpoint with Android.

I need to access this Cloud Endpoint with cURL. I am getting the error:

404 - Not Found

The Endpoint is online, as I can see the index.html at the usual URL:

http://appid.appspot.com/

Hello, Endpoints!

Enter your name and press the button below to call your Google Cloud Endpoints API.

In order to find the URL I used the discovery URL for apis:

https://appid.appspot.com/_ah/api/discovery/v1/apis

That delivered this JSON (sensitive data obfuscated):

{
 "kind": "discovery#directoryList",
 "discoveryVersion": "v1",
 "items": [
  {
   "kind": "discovery#directoryItem",
   "id": "discovery:v1",
   "name": "discovery",
   "version": "v1",
   "title": "APIs Discovery Service",
   "description": "Provides information about other Google APIs, such as what APIs are available, the resource, and method details for each API.",
   "discoveryRestUrl": "https://appid.appspot.com/_ah/api/discovery/v1/apis/discovery/v1/rest",
   "discoveryLink": "./apis/discovery/v1/rest",
   "icons": {
    "x16": "http://www.google.com/images/icons/feature/filing_cabinet_search-g16.png",
    "x32": "http://www.google.com/images/icons/feature/filing_cabinet_search-g32.png"
   },
   "documentationLink": "https://developers.google.com/discovery/",
   "preferred": true
  },
  {
   "kind": "discovery#directoryItem",
   "id": "myApi:v1",
   "name": "myApi",
   "version": "v1",
   "description": "This is an API",
   "discoveryRestUrl": "https://appid.appspot.com/_ah/api/discovery/v1/apis/myApi/v1/rest",
   "discoveryLink": "./apis/myApi/v1/rest",
   "icons": {
    "x16": "https://www.gstatic.com/images/branding/product/1x/googleg_16dp.png",
    "x32": "https://www.gstatic.com/images/branding/product/1x/googleg_32dp.png"
   },
   "preferred": true
  }
 ]
}

I took the discoveryRestUrl for the api myApi.

https://appid.appspot.com/_ah/api/discovery/v1/apis/myApi/v1/rest

{
 "kind": "discovery#restDescription",
 "etag": "\"ODRTh3xaRR64wpeXJSlF33HMN-0/uPLUFYnKhGLgMnhurkbMaKcMDpA\"",
 "discoveryVersion": "v1",
 "id": "myApi:v1",
 "name": "myApi",
 "version": "v1",
 "description": "This is an API",
 "ownerDomain": "backend.appid.companydomain.com",
 "ownerName": "backend.appid.companydomain.com",
 "icons": {
  "x16": "https://www.gstatic.com/images/branding/product/1x/googleg_16dp.png",
  "x32": "https://www.gstatic.com/images/branding/product/1x/googleg_32dp.png"
 },
 "protocol": "rest",
 "baseUrl": "https://appid.appspot.com/_ah/api/myApi/v1/sayHi/",
 "basePath": "/_ah/api/myApi/v1/sayHi/",
 "rootUrl": "https://appid.appspot.com/_ah/api/",
 "servicePath": "myApi/v1/sayHi/",
 "batchPath": "batch",
 "parameters": {
  "alt": {
   "type": "string",
   "description": "Data format for the response.",
   "default": "json",
   "enum": [
    "json"
   ],
   "enumDescriptions": [
    "Responses with Content-Type of application/json"
   ],
   "location": "query"
  },
  "fields": {
   "type": "string",
   "description": "Selector specifying which fields to include in a partial response.",
   "location": "query"
  },
  "key": {
   "type": "string",
   "description": "API key. Your API key identifies your project and provides you with API access, quota, and reports. Required unless you provide an OAuth 2.0 token.",
   "location": "query"
  },
  "oauth_token": {
   "type": "string",
   "description": "OAuth 2.0 token for the current user.",
   "location": "query"
  },
  "prettyPrint": {
   "type": "boolean",
   "description": "Returns response with indentations and line breaks.",
   "default": "true",
   "location": "query"
  },
  "quotaUser": {
   "type": "string",
   "description": "Available to use for quota purposes for server-side applications. Can be any arbitrary string assigned to a user, but should not exceed 40 characters. Overrides userIp if both are provided.",
   "location": "query"
  },
  "userIp": {
   "type": "string",
   "description": "IP address of the site where the request originates. Use this if you want to enforce per-user limits.",
   "location": "query"
  }
 },
 "auth": {
  "oauth2": {
   "scopes": {
    "https://www.googleapis.com/auth/userinfo.email": {
     "description": "View your email address"
    }
   }
  }
 },
 "schemas": {
  "MyBean": {
   "id": "MyBean",
   "type": "object",
   "properties": {
    "data": {
     "type": "string"
    }
   }
  }
 },
 "methods": {
  "sayHi": {
   "id": "myApi.sayHi",
   "path": "{name}",
   "httpMethod": "POST",
   "parameters": {
    "name": {
     "type": "string",
     "required": true,
     "location": "path"
    }
   },
   "parameterOrder": [
    "name"
   ],
   "response": {
    "$ref": "MyBean"
   },
   "scopes": [
    "https://www.googleapis.com/auth/userinfo.email"
   ]
  }
 }
}

I took the URL from here: "baseUrl": "https://appid.appspot.com/_ah/api/myApi/v1/sayHi/".

My curl command:

curl --header "Content-Type: application/json" -X POST -d '{"name": "Testing"}' http://appid.appspot.com/_ah/api/myApi/v1/sayHi

What URL should I use? Is it more likely that something isn't set up correctly?

@Jeff O'Neill - Update 1

Testing using the following URL:

http://appid.appspot.com/myApi/v1/sayHi

<html><head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<title>404 Not Found</title>
</head>
<body text=#000000 bgcolor=#ffffff>
<h1>Error: Not Found</h1>
<h2>The requested URL <code>/myApi/v1/sayHi</code> was not found on this server.</h2>
<h2></h2>
</body></html>

Update 2

I experimented with this Endpoint:

/**
 * A simple endpoint method that takes a name and says Hi back
 */
@ApiMethod(name = "sayHi2", path = "test")
public MyBean sayHi2() {
    MyBean response = new MyBean();
    response.setData("This is a message");

    return response;
}

I can call this with:

curl --header "Content-Type: application/json" -X POST https://appid.appspot.com/_ah/api/myApi/v1/test

I still cannot explain why the original Endpoint cannot be reached, but if adding a path annotation fixes it then I am happy.

1
Try http://appid.appspot.com/myApi/v1/sayHi - gaefan
I now get a 404 Not Found message, but not it returns an HTML response with the following message: <h2>The requested URL <code>/myApi/v1/sayHi</code> was not found on this server.</h2>. - Knossos
When you test with "sayHi2", is this a second method or an entirely different endpoint, also with one method? Can you try the curl with a trailing slash in the URL? - saiyr
Same endpoint with a second method. Trailing slash also makes no difference. - Knossos

1 Answers

1
votes

This is because @Named("name") here is a path parameter. Note this part of your discovery document:

"sayHi": {
 "id": "myApi.sayHi",
 "path": "{name}",

This means to call this method, you append the name to the base path, so the correct command is this:

$ curl --header "Content-Type: application/json" -X POST -d '' https://appid.appspot.com/_ah/api/myApi/v1/sayHi/test
{
 "data": "Hi, test",
 "kind": "myApi#resourcesItem",
 "etag": "\"yN6wlOVUuMN6KwnZ3LSrHdbVqwM/EMLxMt_QPFPG4ZrTIVpiyuCWflg\""
}