Hi to all I created and used openAPI by yaml and I created endpoint that maps 2 cloud functions which use path templating to route the call no error by google sdk cli.
Now I call by POST https://myendpointname-3p5hncu3ha-ew.a.run.app/v1/setdndforrefcli/12588/dnd?key=[apikey] because it's mapped by below open api and reply me "Path does not match any requirement URI template.".
I don't know why path template in endpoint not work I added path_translation: APPEND_PATH_TO_ADDRESS to avoid google to use CONSTANT_ADDRESS default which append id in query string with brutal [name of cloud function]?GETid=12588 and overwrite query parameters with same name.
Somebody can tell me how can I debug the endpoint or the error in openAPI (that have green check ok icon in endpoint)?
# [START swagger]
swagger: '2.0'
info:
description: "Get data "
title: "Cloud Endpoint + GCF"
version: "1.0.0"
host: myendpointname-3p5hncu3ha-ew.a.run.app
# [END swagger]
basePath: "/v1"
#consumes:
# - application/json
#produces:
# - application/json
schemes:
- https
paths:
/setdndforrefcli/{id}/dnd:
post:
summary:
operationId: setdndforrefcli
parameters:
- name: id # is the id parameter in the path
in: path # is the parameter where is in query for rest or path for restful
required: true
type: integer
format: int64
minimum: 1
security:
- api_key: []
x-google-backend:
address: https://REGION-PROJECT-ID.cloudfunctions.net/mycloudfunction
path_translation: APPEND_PATH_TO_ADDRESS
protocol: h2
responses:
'200':
description: A successful response
schema:
type: string
# [START securityDef]
securityDefinitions:
# This section configures basic authentication with an API key.
api_key:
type: "apiKey"
name: "key"
in: "query"
# [END securityDef]
I had the same error, but after did some test I was able to use successfully the path templating (/endpoint/{id}). I resolved this issue as follows:
1 .- gcloud endpoints services deploy openapi-functions.yaml \
--project project
Here you will get a new Service Configuration that you will to use in the next steps.
2.-
chmod +x gcloud_build_image
./gcloud_build_image -s SERVICE \
-c NEWSERVICECONFIGURATION -p project
Its very important change the service configuration with every new deployment of the managed service.
3.- gcloud run deploy SERVICE \
--image="gcr.io/PROJECT/endpoints-runtime-serverless:SERVICE-NEW_SERVICE_CONFIGURATION" \
--allow-unauthenticated \
--platform managed \
--project=PROJECT
Related
I have Cloud Gateway API that connect to Cloud Function.
It worked great with an API key that I generated, but then when I restricted the key to enable access for my specific domain only - example.com, I started to get CORS errors on the client. ( it did worked without domain restriction)
So I enabled CORS in the config file in the Console, the file had no errors, but I still get a CORS error when accessing the API URL from my domain with the key:
https://project-xxxx.uc.gateway.dev/search?key=AIxxxxxxxxx
Config :
swagger: "2.0"
info:
title: projectapi
description: "data api"
version: "1.0.0"
schemes:
- "https"
host: "project-xxxxxxxx.apigateway.xxxxx-xxxxx.cloud.goog"
x-google-endpoints:
- name: "project-xxxxxxxx.apigateway.xxxxx-xxxxx.cloud.goog"
allowCors: True
paths:
"/search":
get:
description: "data"
operationId: "project"
x-google-backend:
address: https://us-central1-projectName.cloudfunctions.net/search
security:
- api_key: [key]
responses:
200:
description: "Success."
schema:
type: string
400:
description: "Invalid"
securityDefinitions:
api_key:
type: "apiKey"
name: "key"
in: "query"
My Cloud Function do allow CORS, and works great if called directly with the link here in the address key.
Why this config wont allow cors for the Gateway ?
Solved !
You must enable the key not only for your domain name, but also for your specific API name from the list, go to APIs & Services => Credentials => API keys => your key => API restrictions => choose your API name from the list !
This allow access to a Function from a specific domain - without using a Balancer.
Having an issue with displaying xml structure defined in swagger file on cloud endpoint portal (Developer portal) for example it does not show the namespaces and example defined, but it works fine when uploaded on swagger editor
Following is example of xml definition declared
MsgResp:
type: object
properties:
Code:
type: string
example: RC_001_SUCCESS
Message:
type: string
example: Message sent
xml:
name: 'MessageResponse'
wrapped: true
namespace: http://MsgResponse
Edit:
Swagger file
# [START swagger]
swagger: '2.0'
info:
title: <Endpoint-name>
description: <Endpoint-name>
version: 1.0.0
# Connects to the cloud run running the ESP Beta 2 image
host: <Endpoint-address> # CloudRun/Esp url
security: []
schemes:
- https
paths:
"/status":
post:
description: "Test API for sending request from system 1 to IIP. "
operationId: "status-api"
# Defines which service it should connect to for backend processing, It can be Cloud function/ Cloud Run url
x-google-backend:
address: https://<Function1-address> # Backend Cloud function URL
deadline: 3600.0
# Defines Authentication mechanism to use, Following mentions to use API KEYS
security:
- api_key: []
# MIME Types expected as request and response
produces:
- "application/xml"
consumes:
- "application/xml"
parameters:
- in: body
name: schema
description: Input Schema for /status
schema:
$ref: '#/definitions/InSchema'
responses:
200:
description: OK
schema:
$ref: '#/definitions/MessageResponse'
404:
description: Not Found
500:
description: Internal Service Error
definitions:
InSchema:
type: object
xml:
name: 'Identifier'
prefix: 'msg'
wrapped: true
namespace: 'http://Identifier'
properties:
Number:
type: integer
LogIdentifier:
type: object
properties:
Code:
type: integer
Type:
type: string
xml:
name: 'LogicalIdentifier'
wrapped: true
namespace: http://LogicalIdentifier
prefix: sample
example: # <----------
Number: 38
LogIdentifier:
Code: 100
Type: CDC
MessageResponse:
type: object
properties:
Code:
type: string
example: SUCCESS
Message:
type: string
example: Message sent
# [START securityDef]
securityDefinitions:
api_key:
type: "apiKey"
name: "key"
in: "query"
# [END securityDef]
As seen on swagger editor
As seen on Cloud endpoint portal/ application portal
According to Cloud Endpoints on Cloud Run Official Documentation, I can only see the .json MimeType is used in the example.
The Cloud Endpoint service definition should be based on OpenAPI Specification v2.0, also known as Swagger 2, which describes the surface of your backend service and any authentication requirements.
So checking the OpenAPI Specification v2.0 in GitHub, I was not able to see xml specification in the MimeType Section. However in the Swagger Official Documentation, I can see that the xml media type is supported as well.
So I would like to ask you to check all the steps provided in the Cloud Endpoint on Cloud Run Official Documentation.
In the screenshot, I can see 404 NOT_FOUND error, this error is mentioned in the Troubleshooting section of Cloud Endpoints, so please have a look into it.
I created the API using GKE and Cloud Endpoint gRPC everything is fine but when I try to access my API from Endpoints Portal this is not working.
EndPoint Portal For API
Enter any id in ayah_id and try to execute you will see error.
ENOTFOUND: Error resolving domain "https://quran.endpoints.utopian-button-227405.cloud.goog"
I don't know why this is not working even my API is running successfully on http://34.71.56.199/v1/image/ayah/ayah-1 I'm using Http Transcoding actual gRPC running on 34.71.56.199:81
I think I missed some configuration steps. Can someone please let me know what I miss.
Update
api_config.yaml
# The configuration schema is defined by service.proto file
# https://github.com/googleapis/googleapis/blob/master/google/api/service.proto
type: google.api.Service
config_version: 3
name: quran.endpoints.utopian-button-227405.cloud.goog
usage:
rules:
# Allow unregistered calls for all methods.
- selector: "*"
allow_unregistered_calls: true
#
# API title to appear in the user interface (Google Cloud Console).
#
title: Quran gRPC API
apis:
- name: quran.Audio
- name: quran.Ayah
- name: quran.Edition
- name: quran.Image
- name: quran.Surah
- name: quran.Translation
Update 2
api_config.yaml
# The configuration schema is defined by service.proto file
# https://github.com/googleapis/googleapis/blob/master/google/api/service.proto
type: google.api.Service
config_version: 3
name: quran.endpoints.utopian-button-227405.cloud.goog
endpoints:
- name: quran.endpoints.utopian-button-227405.cloud.goog
target: "34.71.56.199"
usage:
rules:
# Allow unregistered calls for all methods.
- selector: "*"
allow_unregistered_calls: true
#
# API title to appear in the user interface (Google Cloud Console).
#
title: Quran gRPC API
apis:
- name: quran.Audio
- name: quran.Ayah
- name: quran.Edition
- name: quran.Image
- name: quran.Surah
- name: quran.Translation
api_config_http.yaml
# The configuration schema is defined by service.proto file
# https://github.com/googleapis/googleapis/blob/master/google/api/service.proto
type: google.api.Service
config_version: 3
name: quran.endpoints.utopian-button-227405.cloud.goog
#
# Http Transcoding.
#
# HTTP rules define translation from HTTP/REST/JSON to gRPC. With these rules
# HTTP/REST/JSON clients will be able to call the Quran service.
#
http:
rules:
#
# Image Service transcoding
#
- selector: quran.Image.CreateImage
post: '/v1/image'
body: '*'
- selector: quran.Image.FindImageByAyahId
get: '/v1/image/ayah/{id}'
I have been reviewing Google Cloud Extensible Service Proxy, which promises to be a serverless NGINX instance, however I am unsure on how to proxy to multiple services running in app engine through it, and essentially use it as a gateway. It seems to demand a host in the swagger JSON configuration and an environment variable that points to the endpoint service name, and I don't see how it could proxy to multiple services given this constraint.
My understanding is that you could host the Endpoints ESP using Cloud Run. This would then give you a single URL from which to access it but would spin up enough instances of the ESP if needed. The Open API specification document you would then register with it would contain paths corresponding to each instance of a service you want to expose. For each path, you would then define an x-google-backend pointing to the service URL that each path would resolve against.
EDIT:
the yaml file will look somehow like this:
info:
title: Cloud Endpoints with API Keys
description: Sample API on Cloud Endpoints with multiple App Engine with IAP backend
version: 1.0.0
host: <ENDPOINT_URL>
schemes:
- https
produces:
- application/json
paths:
/hello-gae1:
get:
summary: Greet a user from App Engine
operationId: hello_gae
x-google-backend:
address: https://<PROJECT_ID>.appspot.com
parameters:
- in: query
name: name
required: false
type: string
responses:
'200':
description: A successful response
schema:
type: string
/hello-gae2:
get:
summary: Greet a user from App Engine
operationId: hello_gae
x-google-backend:
address: https://<SERVICE-dot-PROJECT_ID>.appspot.com
parameters:
- in: query
name: name
required: false
type: string
responses:
'200':
description: A successful response
schema:
type: string
/hello-gae3:
get:
summary: Greet a user from App Engine
operationId: hello_gae
x-google-backend:
address: https://<SERVICE-dot-PROJECT_ID>.appspot.com
parameters:
- in: query
name: name
required: false
type: string
responses:
'200':
description: A successful response
schema:
type: string
securityDefinitions:
# This section configures basic authentication with an API key.
api_key:
type: "apiKey"
name: "key"
in: "query"
References:
Getting Started with Endpoints for Cloud Run
I'm now developing REST API with Cloud endpoints and App engine.
I will like to implement api key authentication but it does not work.
Looks good without query params of 'key=${API KEY}'.
# curl -X POST https://hogehoge.com/test -d '{"key":"value"}'
{
"code": 16,
"message": "Method doesn't allow unregistered callers (callers without established identity). Please use API Key or other form of API consumer identity to call this API.",
"details": [
{
"#type": "type.googleapis.com/google.rpc.DebugInfo",
"stackEntries": [],
"detail": "service_control"
}
]
}
But any key can be granted to access to the backend.
# curl -X POST https://hogehoge.com/test?key=aaa -d '{"key":"value"}'
POST is sended.
Of course, API key generated via API management will work.
# curl -X POST https://hogehoge.com/test?key=${realkey} -d '{"key":"value"}'
POST is sended.
Cloud endpoint file definition is
swagger: "2.0"
info:
title: "xxxxxxxxx"
description: "xxxxxxxxx"
version: "1.0.0"
host: "hogehoge.com"
schemes:
- "https"
security: []
paths:
"/test":
post:
description: "test"
operationId: "test"
security:
- api_key: []
parameters:
- name: body
in: body
required: true
schema:
$ref: '#/definitions/testRequest'
responses:
201:
description: "Success"
schema:
$ref: '#/definitions/testResponse'
definitions:
testRequest:
type: object
required:
- data
properties:
data:
type: object
required:
- key
properties:
token:
type: string
example: value
maxLength: 20
testResponse:
type: string
securityDefinitions:
api_key:
type: "apiKey"
name: "key"
in: "query"
What I expect is only key generated via API management will be granted to access.
Let me know how to solve this issue.
Thanks.
It seems that the Service Control API might not be enabled on your project.
In order to check that, you can run
gcloud services list --enabled
If servicecontrol.googleapis.com is not listed in the result of the previous command, you should run
gcloud services enable servicecontrol.googleapis.com
Furthermore, you could check that you have all the required services for Endpoints enabled. You can see how to do this in the documentation