After implementing an api gateway in front of my app engine instances I got a problem stating that the request was blocked because of the CORS header. After searching online I found out that API gateway doesn't provide a way to set the CORS policy, however it also "overwrite" the header sent by my single back-end application. Does I need to implement a load balancer to set an additional Header or there is a way to avoid the overwrite?
Example of API:
paths:
"/login":
post:
description: "Login into the service"
operationId: "login"
x-google-backend:
address: https://project-id.oa.r.appspot.com/api/v1/login
produces:
- "application/json"
responses:
200:
description: "Projects retrieved successfully"
schema:
$ref: "#/definitions/access_token"
401:
description: "Wrong password"
schema:
type: "string"
404:
description: "User not exists"
schema:
type: "string"
parameters:
- in: body
name: user
description: The user to create.
schema:
type: object
required:
- userName
properties:
userName:
type: string
firstName:
type: string
lastName:
type: string
After a lot of trials, I found a simpler solution than implementing a load balancer in front of the gateway:
To use the CORS headers provided by the back-end application it is enough to add a OPTIONS request to the API to avoid headers being overwritten. So, given the login API I just need to add the request like this:
paths:
"/login":
post:
description: "Login into the service"
operationId: "login"
x-google-backend:
address: https://project-id.oa.r.appspot.com/api/v1/login
produces:
- "application/json"
responses:
200:
description: "Projects retrieved successfully"
schema:
$ref: "#/definitions/access_token"
401:
description: "Wrong password"
schema:
type: "string"
404:
description: "User not exists"
schema:
type: "string"
parameters:
- in: body
name: user
description: The user to create.
schema:
type: object
required:
- userName
properties:
userName:
type: string
firstName:
type: string
lastName:
type: string
options:
description: "Cors associated request to login"
operationId: "login cors"
x-google-backend:
address: https://project-id.oa.r.appspot.com/api/v1/login
responses:
200:
description: "Allow"
401:
description: "Cors not allowed"
Related
I'm new in the world of API. I want to do an API using swagger in yaml. My teacher given us a snippet of code that should simulate a login API, but Bearer style. I want to map the generated identifier with the correlated name
paths:
/session:
post:
tags: ["login"]
summary: Logs in the user
description: |-
If the user does not exist, it will be created,
and an identifier is returned.
If the user exists, the user identifier is returned.
operationId: doLogin
requestBody:
description: User details
content:
application/json:
schema:
type: object
properties:
name:
type: string
example: Jason
pattern: 'ˆ.*?$'
minLength: 3
maxLength: 16
required: true
responses:
'201':
description: User log-in action successfully
content:
application/json:
schema:
type: object
properties:
identifier:
# change here if you decide to use an integer
# or any other type of identifier
type: string
example: "abcdef012345"
/session/{identifier}:
get:
summary: Get username
description: Get username from identifier
operationId: getUsername
parameters:
- name: identifier
in: path
description: User ID
required: true
schema:
$ref: "#/components/schemas/User/properties/identifier"
responses:
'200':
description: 'User exists'
content:
application/json:
schema:
$ref: "#/components/schemas/User"
components:
schemas:
User:
type: object
properties:
identifier:
type: string
example: "abcdef012345"
name:
type: string
example: "Jason"
I tried adding the "/session/{identifier}" path, but the get never retrieve the correct information. How can I do it?
Thank you in advance
I'm trying to use GCP API Gateway to create a single endpoint for a couple of my backend services (A,B,C,D), each with their own path structure. I have the Gateway configured for one of the services as follows:
swagger: '2.0'
info:
title: <TITLE>
description: <DESC>
version: 1.0.0
schemes:
- https
produces:
- application/json
paths:
/service_a/match/{id_}:
get:
summary: <SUMMARY>
description: <DESC>
operationId: match_id_
parameters:
- required: true
type: string
name: id_
in: path
- required: true
type: boolean
default: false
name: bool_first
in: query
- required: false
type: boolean
default: false
name: bool_Second
in: query
x-google-backend:
address: <cloud_run_url>/match/{id_}
deadline: 60.0
responses:
'200':
description: Successful Response
'422':
description: Validation
This deploys just fine. But when I hit the endpoint gateway_url/service_a/match/123, it gets routed to cloud_run_url/match/%7Bid_%7D?id_=123 instead of cloud_run_url/match/123.
How can I fix this?
Editing my answer as I misunderstood the issue.
It seems like the { are getting leaked from your configuration as ASCII code, so when you call
x-google-backend:
address: <cloud_run_url>/match/{id_}
deadline: 60.0
it doesn't show the correct ID.
So this should be a leak issue from your yaml file and you can approach this the same way as in this thread about using path params
i have created 2 apis: system and experience for a project. The system had already been deployed into the cloudhub and running successfully. The experience api needs to invoke the system api through a router using the URL:
http://demo-insurance-system-api.us-e2.cloudhub.io
and uriparam is :customer
and queryparams are:?fname=James&lname=Butt
Its working perfectly fine.
but when i want to hit the same url from experience api's requester it gives me
ERROR 2020-05-18 01:58:15,217 [[muleinsurance-exp-api].http.requester.requestConfig.04 SelectorRunner] [event: ] org.mule.runtime.core.internal.exception.OnErrorPropagateHandler:
********************************************************************************
Message : HTTP OPTIONS on resource 'http://demo-insurance-system-api.us-e2.cloudhub.io' failed: not found (404).
Error type : HTTP:NOT_FOUND
Element : muleinsurance-experience-api-main/processors/0 # muleinsurance-exp-api:muleinsurance-experience-api.xml:17
Element XML : <apikit:router config-ref="muleinsurance-experience-api-config"></apikit:router>
(set debug level logging or '-Dmule.verbose.exceptions=true' for everything)
the onpremise testing is done in using postman and the experience url is:
http://localhost:8081/demoapi/customer?fname=James
the experience api raml is:
#%RAML 1.0
title: muleinsurance-experience-api
version: 1.0.0
traits:
client-id-required:
headers:
client_id:
type: string
client_secret:
type: string
responses:
401:
description: Unauthorized, The client_id or client_secret are not valid or the client does not have access.
404:
description: No Record found.
429:
description: The client used all of it's request quota for the current period.
500:
description: Server error ocurred
503:
description: Contracts Information Unreachable.
/demoapi:
/{searchString}:
get:
description: invokes either customer or policy request
queryParameters:
fname:
description: first name
example: Sumitra
required: false
type: string
lname:
description: Last name
example: Ojha
required: false
type: string
dob:
description: Date of Birth
example: 1/2/2003
required: false
type: string
customerID:
description: CustomerID
example: BU79786
required: false
type: string
policytype:
description: type of policy taken
example: Personal Auto
required: false
type: string
responses:
200:
body:
application/json:
example:
{"message": "connecting to System API"}
here i am adding the HTTP request xml snippet:
<choice doc:name="Choice" doc:id="444a5cd6-4aee-441a-8736-2d2fff681e2e" >
<when expression="#[attributes.uriParams.searchString == 'customer']">
<http:request method="GET" doc:name="Request" doc:id="30958d05-467a-41b1-bef3-83426359f2aa" url="http://demo-insurance-system-api.us-e2.cloudhub.io"><http:uri-params ><![CDATA[#[output application/java
---
{ customer : attributes.uriParams.searchString}]]]></http:uri-params>
<http:query-params ><![CDATA[#[output application/java
---
{ fname : vars.fname,
lname : vars.lname,
dob : vars.dob}]]]>
kindly point out where i need to improve. thanks in advance.
The problem is indicated in the error message: HTTP OPTIONS on resource 'http://demo-insurance-system-api.us-e2.cloudhub.io' failed: not found (404).
It looks like your HTTP Request in the experience API is using the HTTP Options method. The RAML indicates that the API only accepts the HTTP GET method. In the XML it should look like: <http:request method="GET" ...
I am using OpenApi do document an API, i have a path /Login which lets me specify Username and Password as parameters and returns a Bearer style JWT in the "authorization" header in the response.
For further use in the API this JWT is used with the "Authorize" mechanism so the other paths can be accessed.
Sadly the authorization header is only visible if i open the network tracing in my browser.
Therefore my question, can i somehow tweak my OpenAPI YAML so the value is displayed and can then be copy/pasted to the authorization for the rest of the API. I am using the latest swagger editor (https://editor.swagger.io/)
This is what i have specified
paths:
/Login:
post:
servers:
- url: ....
description: Local test server
tags:
- Login
summary: Logs into the API and returns the authorization.
description: Username and Password are passed in header
security: []
#- bearerAuth: []
parameters:
- $ref: '#/components/parameters/Username'
- $ref: '#/components/parameters/Password'
responses:
200:
description: Successful response
content:
application/json:
schema:
$ref: '#/components/schemas/Login'
headers:
authorization:
$ref: '#/components/headers/authorization'
parameters:
Username:
name: Username
in: header
description: Username to authorize with
schema:
type: string
Password:
name: Password
in: header
description: Password to authorize with
schema:
type: string
headers:
authorization:
schema:
type: string
description: Authorization token.
I'm defining a resource that you POST to with a non-JSON body. It's just a string like form parameters. Something like what happens with OAuth:
grant_type=&code=&redirect_uri=
How can I document that on Swagger? Do I have to use formParam format instead of body? Everything I put into body it converts to JSON examples.
TokenRequest:
properties:
grant_type:
type: string
description: OAuth Grant Type
enum:
- authorization_code
- refresh
code:
type: string
description: Authorization Code obtained from /authorize required if grant_type = au
redirect_uri:
type: string
description: Defined Redirect URI Example - https://example.com/callback
refresh_token:
type: string
description: Required if grant_type = refresh
Here is an example on how to document the form data:
post:
tags:
- pet
summary: Updates a pet in the store with form data
description: ''
operationId: updatePetWithForm
consumes:
- application/x-www-form-urlencoded
produces:
- application/xml
- application/json
parameters:
- name: petId
in: path
description: ID of pet that needs to be updated
required: true
type: integer
format: int64
- name: name
in: formData
description: Updated name of the pet
required: false
type: string
- name: status
in: formData
description: Updated status of the pet
required: false
type: string
responses:
'405':
description: Invalid input
security:
- petstore_auth:
- 'write:pets'
- 'read:pets'
But in your case, it seems you want to define OAuth setting so please refer to Swagger Spec 2.0 for more information. Here is an example for PetStore:
securityDefinitions:
petstore_auth:
type: oauth2
authorizationUrl: 'http://petstore.swagger.io/api/oauth/dialog'
flow: implicit
scopes:
'write:pets': modify pets in your account
'read:pets': read your pets
api_key:
type: apiKey
name: api_key
in: header