I have more than 30 methods exposed using Cloud Endpoints. All works perfectly except 2 methods where I have following specification, in short
From yaml I have marked in bold the particular part where issue occurs. If I remove, file is properly parsed and deployed.
Please refer the last 4 lines starting from --> in: "formData"
post:
tags:
- "Companies"
description: "Add a new company"
operationId: "addCompany"
consumes:
- multipart/form-data
parameters:
- in: "formData"
name: "name"
description: "name of the company"
type: "string"
- in: "formData"
name: "map"
description: "map of the company (JSON)"
type: "string"
required: true
- in: "formData"
name: "hardnesses"
description: "list of hardnesses seperate by semicolon ;"
type: "string"
- in: "formData"
name: "file"
description: "Company logo"
type: "file"
So it means will I not be able to upload a file?
Thanks for your valuable inputs.
(Issue is in Github: https://github.com/GoogleCloudPlatform/java-docs-samples/issues/1392 )
Google Cloud Endpoints does not currently support parameter of type "file".
Related answer
Related
I'm trying to create the following api config for GCP API Gateway (ommitted real backend URL):
swagger: '2.0'
info:
title: upload
description: upload
version: 1.0.0
schemes:
- https
produces:
- application/json
security:
- api_key: [ ]
paths:
/upload:
post:
summary: uploads a file.
consumes:
- multipart/form-data
operationId: uploadFile
parameters:
- in: formData
name: file
description: The file to upload.
required: true
type: file
responses:
'200':
description: upload successful
x-google-backend:
address: https://XXXXX.XXXXX
path_translation: APPEND_PATH_TO_ADDRESS
securityDefinitions:
api_key:
type: "apiKey"
name: "key"
in: "query"
Running gcloud (replaced real variables with placeholders)
gcloud api-gateway api-configs create uploadconfig --api=[API] --openapi-spec=openapi.yaml --project=[MYPROJECT] --backend-auth-service-account=[ACCOUNT]
This results in this error message:
ERROR: (gcloud.api-gateway.api-configs.create) INVALID_ARGUMENT: Cannot convert to service config.
'location: "unknown location"
kind: ERROR
message: "http: repeated message field 'google.protobuf.Struct.fields' referred to by message 'UploadFileRequest' cannot be mapped as an HTTP parameter."
location: "unknown location"
kind: ERROR
message: "http: cyclic message field 'google.protobuf.Struct.FieldsEntry.value' referred to by message 'UploadFileRequest' in method 'method 1.xxxxxxx.UploadFile' cannot be mapped as an HTTP parameter."
I verified the gcloud command with a different api configurations and backends.
The config itself seems fine, i.e. it validates with Swagger editor, still gcloud won't accept it.
How do I define a file upload via API Gateway?
As per file upload Endpoints does not accept the type: file for file upload parameters, type: string should be used instead.And I tried config with changed parameters and it validates with Swagger editor results are here.
With SwaggerHub and OpenAPI 2 spec, this is how I got this file upload to work. Let me know if you have any questions. This is written in YAML as opposed to JSON spec. It took some reading and some experimentation, but here's the Gcloud documentation: https://cloud.google.com/storage/docs/uploading-objects
And the SwaggerHub info as well: https://swagger.io/docs/specification/2-0/file-upload/
/upload/storage/v1/b/{bucket}/o?uploadType=media&name={objectName}:
post:
summary: Upload an object directly to a bucket
description: Upload an object directly to a bucket
consumes:
- multipart/form-data
produces:
- application/json
parameters:
- in: header
name: Authorization
type: string
required: true
- in: path
name: bucket
required: true
type: string
description: The name of the bucket to upload to.
- in: path
name: objectName
required: true
type: string
description: The name the object will receive in the bucket.
- in: header
name: Content-Type
type: string
required: true
description: The content type of the upload. Ex. text/plain
- in: formData
name: fileToUpload
type: file
description: The file to upload.
responses:
200:
description: OK
204:
description: Success - No Content
400:
description: Bad Request
401:
description: Insufficient Privileges
404:
description: Not Found
It DOES accept type: file in the formData request.
I'm trying to create an API gateway on Google Cloud Platform, after filling in all the fields and clicking on create gateway the following error message appears:
Cannot convert to service config. 'location: "unknown location" kind: ERROR message: "Unable to parse the content. while parsing a block mapping\n in 'reader', line 1, column 1:\n swagger: '2.0'\n ^\nexpected , but found BlockMappingStart\n in 'reader', line 2, column 5:\n info:\n ^\n\n at [Source: (StringReader); line: 1, column: 15]" '
I believe this is related to the configuration of the Yaml file that is required in the API Spec field as shown in the image below:
My yaml file is configured as follows:
swagger: '2.0'
info:
title: API Gateway for Cycle
description: "Send a deal object for the data to be treated"
version: "1.0.0"
host: teste.apigateway.project-teste-homolog.cloud.goog
schemes:
- "https"
produces:
- "application/json"
paths:
"/data-verification-homologation":
post:
x-google-backend:
address: URL.example
description: "Jailson esteve aqui =)"
operationId: "dataVerification"
parameters:
-
name: iataCode
in: query
required: true
type: string
responses:
200:
description: "Sucess"
schema:
type: string
400:
description: "Error"
I've already checked the following google documentation https://cloud.google.com/endpoints/docs/grpc/troubleshoot-config-deployment, but I couldn't solve the error.
Your indentation is incorrect.
swagger: "2.0"
info:
title: "API Gateway for Cycle"
description: ...
YAML requires very precise indentation.
See YAML Swagger (OpenAPI) example here: https://swagger.io/docs/specification/basic-structure/
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 have recently started learning Swagger for APi documentation. However, when I go to localhost:5000/apidocs, I see APIs that I added but all APIs are with no parameters even when I have described parameters in my yml file. I couldn't find anything relevant on the internet.
Here is my YML code:
paths:
/api/ppp:
get:
tags:
- "user"
summary: "Find User by uID"
description: "Returns a single user info"
operationId: "getuserById"
produces:
- "application/xml"
- "application/json"
parameters:
- name: "userId"
in: "path"
description: "ID of user to return"
required: true
type: "uuid"
and here is how I am adding swagger to the api
#swag_from('pathto/swagger.yml')
Similarly, I have another doubt. We define schema in the yml specification file. I want to know what exactly those schema represent and is it necessary to use them?
Attached is a screenshot of the APIdocs page
try this:
tags:
- user
summary: "Find User by uID"
description: "Returns a single user info"
operationId: "getuserById"
produces:
- "application/xml"
- "application/json"
parameters:
- name: "userId"
in: "path"
description: "ID of user to return"
required: true
type: "uuid"
My setup contains google-endpoints with google-cloud-functions as my backend.
Google endpoints is defined with the following swagger v2 yaml:
swagger: "2.0"
info:
description: "yada..."
version: "0.0.1"
title: "yadada.."
termsOfService: "http://swagger.io/terms/"
contact:
name: "blah"
email: "email#mail.com"
url: "https://example.com"
host: "(generated service url by google when endpoints is deployed, i.e. 'api-gateway-xyz123123-ew.a.run.app')"
tags:
- name: "Documents"
description: "blah"
schemes:
- "https"
paths:
/api/documents:
post:
tags:
- "Documents"
summary: "Add a new document"
description: ""
security:
- firebase: []
operationId: "addDocument"
x-google-backend:
address: "(cloud functions http url)/documents"
consumes:
- "application/json"
produces:
- "application/json"
parameters:
- in: "body"
name: "body"
description: "Document supplied"
required: true
schema:
$ref: "#/definitions/Document"
responses:
201:
description: "The document was successfully created."
schema:
$ref: "#/definitions/Document"
400:
description: "Invalid input. See response for details"
schema:
items:
$ref: "#/definitions/Error"
/api/documents/{document_id}:
get:
tags:
- "Documents"
summary: "Get a document with the given ID"
description: ""
security:
- firebase: []
operationId: "getDocument"
x-google-backend:
address: "(cloud function http url)/documents/"
path_translation: APPEND_PATH_TO_ADDRESS
produces:
- "application/json"
parameters:
- in: "path"
name: "document_id"
description: "ID of the document to modify"
required: true
type: "string"
responses:
200:
description: "success."
schema:
type: "array"
items:
$ref: "#/definitions/Document"
404:
description: "Document not found"
schema:
items:
$ref: "#/definitions/Error"
securityDefinitions:
firebase:
authorizationUrl: ""
flow: "implicit"
type: "oauth2"
x-google-issuer: "https://securetoken.google.com/%%GOOGLE_PROJECT_ID%%"
x-google-jwks_uri: "https://www.googleapis.com/service_accounts/v1/metadata/x509/securetoken#system.gserviceaccount.com"
x-google-audiences: "%%GOOGLE_PROJECT_ID%%"
definitions:
(a lot of type definitions)
This works with the POST endpoint without any problems.
The problem is with the GET REST endpoint where the path variable is not passed correctly to the backend.
As in https://cloud.google.com/endpoints/docs/openapi/openapi-extensions I tried to add the x-google-backend parameter as in the swagger api above. (path_translation: APPEND_PATH_TO_ADDRESS).
However this does not work.
I get an Unauthorized Error (403) as the cloud function is not hit by the endpoints frontend.
Currently I use an ugly workaround without the path_translation parameter which translates the google endpoints path variable to a query parameter in the cloud function backend with the same name. I.e. in the backend the url /documents?document_id=xyz is called.
(What I try to achieve is to pass the call with the backend url /documents/{document_id})
Does anyone know how to configure path based parameters correctly so that they are passed correctly to the cloud function backend?
Thank you in advance.
Regards,
Sebastian
TL;DR:
I assume that your 403 error isn't the correct error. It should be a 404, but because the endpoint is unknown, I guess that 403 is answered.
Cloud Endpoint is frustrating about this behavior. With the path_translation: APPEND_PATH_TO_ADDRESS, you think that your final called address will be /documents/{document_id}, but NO. The full openAPI path is append to your backend address, in your case: /documents/api/documents/{document_id}
That's why the endpoint doesn't exist and you should have a 404 (and not a 403).
For more details, you can have a look to this page.
Note: I'm in relation with Google team on this topic, and it will take time before having an update on this behavior.