Secure "hello world" Google cloud function - google-cloud-platform

I need a very secure cloud function so I'm trying to put it behind a API Gateway.
The function works fine when I call it directy passing a Bearer token in header:
https://us-central1-<my-project>.cloudfunctions.net/<my-hello-function>
However I want to allow it to be used with a API token thru API Gateway (and then do something more useful than saying "hello"):
https://my-gateway-xxxxxxxx.uc.gateway.dev/v1/stats&key=<my-API-token>
When I try to call it I get:
{
"code": 404,
"message": "Path does not match any requirement URI template."
}
My API Gateway config file:
swagger: "2.0"
info:
title: my-gateway
version: "1.0.0"
basePath: "/v1"
schemes:
- "https"
produces:
- application/json
paths:
/stats:
get:
tags:
- "stats"
summary: "get service stats"
description: "Returns statistics"
operationId: "hello_world"
#produces:
#- "application/json"
parameters:
- name: "since"
in: "header"
description: "Date to retrieve information"
required: false
type: "string"
format: "date"
x-google-backend:
address: https://us-central1-<my-project>.cloudfunctions.net/<my-hello-function>
path_translation: CONSTANT_ADDRESS
protocol: h2
responses:
"200":
description: "successful operation"
schema:
$ref: "#"
"400":
description: "Invalid datetime supplied"
"404":
description: "Unknown path"
security:
- api_key: []
securityDefinitions:
api_key:
type: "apiKey"
name: "api_key"
in: "query"
definitions:
ApiResponse:
type: "object"
properties:
code:
type: "integer"
format: "int32"
type:
type: "string"
message:
type: "string"
What's missing? What am I doing wrong?

I tested your file and I reviewed your HTTP call. I noticed that in your security definitions you are naming the API key as api_key but in your URL you are using the parameter key, also, it is not necessary to set path_translation: CONSTANT_ADDRESS because this is the default directive
Additionally, you can check if your gateway is using the latest configuration.
This is the config that I used and works as expected (I changed the apikey to key and I removed path_translation)
swagger: "2.0"
info:
title: my-gateway
version: "1.0.0"
basePath: "/v1"
schemes:
- "https"
produces:
- application/json
paths:
/stats:
get:
tags:
- "stats"
summary: "get service stats"
description: "Returns statistics"
operationId: "hello_world"
parameters:
- name: "since"
in: "header"
description: "Date to retrieve information"
required: false
type: "string"
format: "date"
x-google-backend:
address: https://us-central1-[myproject].cloudfunctions.net/[functionname]
protocol: h2
responses:
"200":
description: "successful operation"
schema:
$ref: "#"
"400":
description: "Invalid datetime supplied"
"404":
description: "Unknown path"
security:
- api_key: []
securityDefinitions:
api_key:
type: "apiKey"
name: "key"
in: "query"
definitions:
ApiResponse:
type: "object"
properties:
code:
type: "integer"
format: "int32"
type:
type: "string"
message:
type: "string"

Related

IBM API Connect: Set-Variable does not work

I'm a novice in IBM API Connect. What I want to realize is to pass the client certificate used in the mutual TLS connection between an API caller and IBM API Connect to a backend server as a value of Client-Cert HTTP header.
I thought that Set-Variable could be used for the purpose, but a request forwarded to the backend server does not contain the Client-Cert HTTP header.
Could anyone help me out?
swagger: '2.0'
info:
version: 1.0.0
title: test
x-ibm-name: test
basePath: /test
x-ibm-configuration:
properties:
target-url:
value: https://httpdump.io/tqvg_
description: URL of the proxy policy
encoded: false
cors:
enabled: true
gateway: datapower-api-gateway
type: rest
phase: realized
enforced: true
testable: true
assembly:
execute:
- set-variable:
version: 2.0.0
title: client-cert
actions:
- value: ':$(application.certificate.Base64):'
type: string
add: Client-Cert
- value: My-Value
add: My-Header
type: string
description: >-
Set the client certificate used in the mutual TLS connection to the
Client-Cert HTTP header in the format defined in "Client-Cert HTTP
Header Field".
- invoke:
version: 2.2.0
title: invoke
backend-type: detect
header-control:
type: blocklist
values: []
parameter-control:
type: blocklist
values: []
http-version: HTTP/1.1
timeout: 60
verb: POST
chunked-uploads: true
persistent-connection: true
cache-response: protocol
cache-ttl: 900
stop-on-error: []
websocket-upgrade: false
target-url: $(target-url)
graphql-send-type: detect
finally: []
activity-log:
enabled: true
success-content: activity
error-content: payload
paths:
/:
get:
responses:
'200':
description: success
schema:
type: string
consumes: []
produces: []
put:
responses:
'200':
description: success
schema:
type: string
consumes: []
produces: []
post:
responses:
'200':
description: success
schema:
type: string
consumes: []
produces: []
delete:
responses:
'200':
description: success
schema:
type: string
consumes: []
produces: []
head:
responses:
'200':
description: success
schema:
type: string
consumes: []
produces: []
patch:
responses:
'200':
description: success
schema:
type: string
consumes: []
produces: []
schemes:
- https
Your variable name should be message.headers.Client-Cert if you want to add a header. Otherwise you're just creating an internal variable that never gets read.

Postman login endpoint definition api OpenApi 3.0

I have just started using postman so that I can serve my front end.
I have managed to create a mock service and define some schema and some endpoints. I have also added the bearer authorization. I do not understand how to implement the login endpoint to get back the auth token.
I understand it must be a POST, with no security check, sending email and psw
What other values should I consider?
openapi: 3.0.0
info:
version: 'draft'
title: 'MY API'
license:
name: MIT
servers:
- url: 'https://e9d52583-3413-476e-b0a9-02c4151be665.mock.pstmn.io'
paths:
/user:
get:
summary: 'User: Returns details about a particular user'
operationId: listUser
tags:
- user
parameters:
- name: id
in: query
description: ID of the user
required: true
schema:
type: integer
format: int32
responses:
'200':
description: 'User: Details about a user by ID'
headers:
x-next:
description: A link to the next page of responses
schema:
type: string
content:
application/json:
schema:
$ref: '#/components/schemas/User'
default:
description: Unexpected error
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/brands:
get:
summary: 'Brands: List all brands'
operationId: listBrands
tags:
- brands
responses:
200:
description: 'Brands: An array of brands'
headers:
x-next:
description: 'Brands: A link to the next page of responses'
schema:
type: string
content:
application/json:
schema:
$ref: "#/components/schemas/Brands"
401:
description: 'Not authorized'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
default:
description: Unexpected error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/brand:
get:
summary: 'Brand: Returns details about a particular brand'
operationId: listBrand
tags:
- brand
parameters:
- name: id
in: query
description: ID of the user
required: true
schema:
type: integer
format: int32
responses:
'200':
description: 'Brand: Details about a brand by ID'
headers:
x-next:
description: A link to the next page of responses
schema:
type: string
content:
application/json:
schema:
$ref: '#/components/schemas/Brand'
default:
description: Unexpected error
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
components:
schemas:
User:
type: object
required:
- id
- name
properties:
id:
type: integer
format: int64
name:
type: string
tag:
type: string
Brand:
type: object
required:
- id
- name
properties:
id:
type: integer
format: int64
name:
type: string
tag:
type: string
Brands:
type: array
items:
$ref: "#/components/schemas/Brand"
Error:
type: object
required:
- code
- message
properties:
code:
type: integer
format: int32
message:
type: string
securitySchemes:
bearerAuth:
type: http
scheme: 'bearer'
bearerFormat: 'JWT'
responses:
UnauthorizedError:
description: Access token is missing or invalid
security:
- bearerAuth: []

Google Cloud Endpoints POST returning Jwt issuer is not configured

I am setting up a POST request on our Google Cloud Endpoints, but its always returning:
{
"message": "Jwt issuer is not configured",
"code": 401
}
I believe I checked everything but it still not working. I am not sure if there is a missing file (Node or Python file?), I am not sure. Here is my openapi.yaml file:
# [START swagger]
swagger: "2.0"
info:
title: "xxxxx"
description: "API endpoints and service functions"
version: "1.0.0"
termsOfService: "https://xxxxxx.com/terms"
contact:
name: "xxxxx"
url: "xxxxx"
email: "xxxxx"
license:
name: "Apache 2.0"
url: "http://www.apache.org/licenses/LICENSE-2.0.html"
host: "xxxxx.com"
x-google-endpoints:
- name: "xxxxx"
allowCors: true
x-google-allow: "configured"
x-google-issuer: "accounts.google.com"
x-google-jwks_uri: "https://www.googleapis.com/robot/v1/metadata/x509/xxxxx.iam.gserviceaccount.com"
x-google-backend:
address: "https://xxxxx.cloudfunctions.net"
jwt_audience: "xxxxx.apps.googleusercontent.com"
path_translation: "CONSTANT_ADDRESS"
deadline: 15.0
protocol: "h2"
security:
- api_key: []
consumes:
- "application/json"
- "text/html"
produces:
- "application/json"
- "text/html"
schemes:
- "https"
# [END swagger]
paths:
"/auth/google_id":
get:
description: "Returns the requests' authentication information."
operationId: "authGoogleId"
produces:
- "application/json"
responses:
200:
description: "Authenication info."
schema:
$ref: "#/definitions/authInfoResponse"
security:
- google_id: []
api_key: []
"/auth/google_sa":
get:
description: "Returns authentication from request"
operationId: "authGoogleSA"
produces:
- "application/json"
responses:
200:
description: "Authentication info"
schema:
$ref: "#/definitions/authInfoResponse"
security:
- google_sa: []
api_key: []
"/auth/firebase":
get:
description: "Firebase authentication"
operationId: "authFirebase"
produces:
- "application/json"
responses:
200:
description: "Firebase success response"
schema:
$ref: "#/definitions/authInfoResponse"
security:
- firebase: []
api_key: []
"/echo":
post:
description: "Echo back a given message."
operationId: "echo"
produces:
- "application/json"
responses:
200:
description: "Echo success message"
schema:
$ref: "#/definitions/echoMessage"
parameters:
- description: "Message to echo"
in: body
name: message
required: true
schema:
$ref: "#/definitions/echoMessage"
security:
- google_id: []
api_key: []
"/query_tables":
get:
summary: "Query data tables"
operationId: "query_tables"
produces:
- "application/json"
parameters:
- name: "table"
in: "path"
description: "Table to search"
required: true
type: "string"
- name: "column"
in: "path"
description: "Column to select"
required: true
type: "string"
x-google-backend:
address: "https://xxxxx.cloudfunctions.net/query_tables"
protocol: "h2"
path_translation: "CONSTANT_ADDRESS"
responses:
200:
description: "Success"
schema:
$ref: "#/definitions/tableObject"
404:
description: "Failure"
schema:
$ref: "#/definitions/GeneralError"
security:
- google_id: [
"email:https://www.googleapis.com/auth/userinfo.email",
"profile:https://www.googleapis.com/auth/userinfo.profile"
]
api_key: []
definitions:
# [START responseDef]
echoMessage:
type: "string"
properties:
message:
type: "string"
tableObject:
type: "object"
properties:
message:
type: "string"
authInfoResponse:
properties:
id:
type: "string"
description: "First name of the user"
first_name:
type: "string"
description: "First name of the user"
last_name:
type: "string"
description: "Last name of the user"
email:
type: "string"
description: "Email address of the user"
picture:
type: "string"
description: "Image URL of the user"
NotFound:
description: "Entity not found"
IllegalInput:
description: "Illegal input for operation"
GeneralError:
description: "General error"
# [END responseDef]
securityDefinitions:
# [START securityDef]
api_key:
type: "apiKey"
name: "key"
in: "query"
google_id:
type: "oauth2"
flow: "implicit"
authorizationUrl: "https://accounts.google.com/o/oauth2/auth"
x-google-issuer: "accounts.google.com"
x-google-jwks_uri: "https://www.googleapis.com/oauth2/v3/certs"
x-google-audiences: "xxxxx"
x-google-jwt-locations:
- header: "Authorization"
value_prefix: "Bearer "
google_sa:
type: "oauth2"
flow: "implicit"
authorizationUrl: "https://accounts.google.com/o/oauth2/auth"
x-google-issuer: "xxxxx.iam.gserviceaccount.com"
x-google-jwks_uri: "https://www.googleapis.com/robot/v1/metadata/x509/#xxxxx.iam.gserviceaccount.com"
x-google-audiences: "xxxxx.apps.googleusercontent.com"
x-google-jwt-locations:
- header: "Authorization"
value_prefix: "Bearer "
# [START firebaseAuth]
firebase:
authorizationUrl: ""
flow: "implicit"
type: "oauth2"
x-google-issuer: "https://securetoken.google.com/mpa-work-flows"
x-google-jwks_uri: "https://www.googleapis.com/service_accounts/v1/metadata/x509/xxxxx.gserviceaccount.com"
x-google-audiences: "xxxxx"
x-google-locations:
- header: "Authorization"
value_prefix: "Bearer "
# [END firebaseAuth]
# [END securityDef]
I am a beginner when it comes to Cloud endpoints. Hopefully you can help. Thank you!

How can I create api gateways using boto3 and proxy requests to it from base flask-serverless api?

I would like to use flask application as a lambda function and serverless framework to deploy it on AWS platform.
I would like to know how can I create REST API on API GATEWAY service from swagger file using boto3 and make proxy request to that newly created api.
So, main goal is to have flask lambda function (as shown in example belove) deployed using serverless framework and it's gateway used as a starting point. Then it shoud be able to recieve:
POST request on /create path to create new API on API GATEWAY from swagger file
GET request on api/{api} to acces previously created API with POST request
Further explanation:
Let's say starting api on api gateway is test.com (deployed with serverless framework and flask lambda function as described before).
Sending swagger file swagger-pets.yaml (full file shown belove) through POST request on /create route shoud create api on api gateway called pet-store.
That pet-store API should now be able to be called and used as:
GET test.com/api/pet-store/pet/{petID} - returns pet with passed ID
POST /test.com/api/pet-store/pet - adds a new pet
etc (same as sample swagger petstore server https://editor.swagger.io/).
I managed to create (import) API from example swagger file using only boto3 import_rest_api method to api gateway but it only added resources (paths) on api gateway and I don't know how to use it.
Flask code should look something like this:
# app.py
from flask import Flask
app = Flask(__name__)
#app.route("/")
def hello():
return "Hello World!"
#app.route("/create", methods=["POST"])
def create():
# creates api on api gateway from swagger file using boto3
#app.route("/api/<path:subpath>", methods=["GET", "POST"])
def proxy(subpath):
# proxy to any api gateway
Serverless framework code example:
# serverless.yml
service: serverless-flask
plugins:
- serverless-python-requirements
- serverless-wsgi
custom:
wsgi:
app: app.app
packRequirements: false
pythonRequirements:
dockerizePip: non-linux
provider:
name: aws
runtime: python3.6
stage: dev
region: us-east-1
functions:
app:
handler: wsgi.handler
events:
- http: ANY /
- http: 'ANY {proxy+}'
Swagger file example:
swagger: "2.0"
info:
description: "This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters."
version: "1.0.0"
title: "Swagger Petstore"
termsOfService: "http://swagger.io/terms/"
contact:
email: "apiteam#swagger.io"
license:
name: "Apache 2.0"
url: "http://www.apache.org/licenses/LICENSE-2.0.html"
host: "petstore.swagger.io"
basePath: "/v2"
tags:
- name: "pet"
description: "Everything about your Pets"
externalDocs:
description: "Find out more"
url: "http://swagger.io"
- name: "store"
description: "Access to Petstore orders"
- name: "user"
description: "Operations about user"
externalDocs:
description: "Find out more about our store"
url: "http://swagger.io"
schemes:
- "https"
- "http"
paths:
/pet:
post:
tags:
- "pet"
summary: "Add a new pet to the store"
description: ""
operationId: "addPet"
consumes:
- "application/json"
- "application/xml"
produces:
- "application/xml"
- "application/json"
parameters:
- in: "body"
name: "body"
description: "Pet object that needs to be added to the store"
required: true
schema:
$ref: "#/definitions/Pet"
responses:
"405":
description: "Invalid input"
security:
- petstore_auth:
- "write:pets"
- "read:pets"
put:
tags:
- "pet"
summary: "Update an existing pet"
description: ""
operationId: "updatePet"
consumes:
- "application/json"
- "application/xml"
produces:
- "application/xml"
- "application/json"
parameters:
- in: "body"
name: "body"
description: "Pet object that needs to be added to the store"
required: true
schema:
$ref: "#/definitions/Pet"
responses:
"400":
description: "Invalid ID supplied"
"404":
description: "Pet not found"
"405":
description: "Validation exception"
security:
- petstore_auth:
- "write:pets"
- "read:pets"
/pet/findByStatus:
get:
tags:
- "pet"
summary: "Finds Pets by status"
description: "Multiple status values can be provided with comma separated strings"
operationId: "findPetsByStatus"
produces:
- "application/xml"
- "application/json"
parameters:
- name: "status"
in: "query"
description: "Status values that need to be considered for filter"
required: true
type: "array"
items:
type: "string"
enum:
- "available"
- "pending"
- "sold"
default: "available"
collectionFormat: "multi"
responses:
"200":
description: "successful operation"
schema:
type: "array"
items:
$ref: "#/definitions/Pet"
"400":
description: "Invalid status value"
security:
- petstore_auth:
- "write:pets"
- "read:pets"
/pet/findByTags:
get:
tags:
- "pet"
summary: "Finds Pets by tags"
description: "Muliple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing."
operationId: "findPetsByTags"
produces:
- "application/xml"
- "application/json"
parameters:
- name: "tags"
in: "query"
description: "Tags to filter by"
required: true
type: "array"
items:
type: "string"
collectionFormat: "multi"
responses:
"200":
description: "successful operation"
schema:
type: "array"
items:
$ref: "#/definitions/Pet"
"400":
description: "Invalid tag value"
security:
- petstore_auth:
- "write:pets"
- "read:pets"
deprecated: true
/pet/{petId}:
get:
tags:
- "pet"
summary: "Find pet by ID"
description: "Returns a single pet"
operationId: "getPetById"
produces:
- "application/xml"
- "application/json"
parameters:
- name: "petId"
in: "path"
description: "ID of pet to return"
required: true
type: "integer"
format: "int64"
responses:
"200":
description: "successful operation"
schema:
$ref: "#/definitions/Pet"
"400":
description: "Invalid ID supplied"
"404":
description: "Pet not found"
security:
- api_key: []
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"
delete:
tags:
- "pet"
summary: "Deletes a pet"
description: ""
operationId: "deletePet"
produces:
- "application/xml"
- "application/json"
parameters:
- name: "api_key"
in: "header"
required: false
type: "string"
- name: "petId"
in: "path"
description: "Pet id to delete"
required: true
type: "integer"
format: "int64"
responses:
"400":
description: "Invalid ID supplied"
"404":
description: "Pet not found"
security:
- petstore_auth:
- "write:pets"
- "read:pets"
/pet/{petId}/uploadImage:
post:
tags:
- "pet"
summary: "uploads an image"
description: ""
operationId: "uploadFile"
consumes:
- "multipart/form-data"
produces:
- "application/json"
parameters:
- name: "petId"
in: "path"
description: "ID of pet to update"
required: true
type: "integer"
format: "int64"
- name: "additionalMetadata"
in: "formData"
description: "Additional data to pass to server"
required: false
type: "string"
- name: "file"
in: "formData"
description: "file to upload"
required: false
type: "file"
responses:
"200":
description: "successful operation"
schema:
$ref: "#/definitions/ApiResponse"
security:
- petstore_auth:
- "write:pets"
- "read:pets"
/store/inventory:
get:
tags:
- "store"
summary: "Returns pet inventories by status"
description: "Returns a map of status codes to quantities"
operationId: "getInventory"
produces:
- "application/json"
parameters: []
responses:
"200":
description: "successful operation"
schema:
type: "object"
additionalProperties:
type: "integer"
format: "int32"
security:
- api_key: []
/store/order:
post:
tags:
- "store"
summary: "Place an order for a pet"
description: ""
operationId: "placeOrder"
produces:
- "application/xml"
- "application/json"
parameters:
- in: "body"
name: "body"
description: "order placed for purchasing the pet"
required: true
schema:
$ref: "#/definitions/Order"
responses:
"200":
description: "successful operation"
schema:
$ref: "#/definitions/Order"
"400":
description: "Invalid Order"
/store/order/{orderId}:
get:
tags:
- "store"
summary: "Find purchase order by ID"
description: "For valid response try integer IDs with value >= 1 and <= 10. Other values will generated exceptions"
operationId: "getOrderById"
produces:
- "application/xml"
- "application/json"
parameters:
- name: "orderId"
in: "path"
description: "ID of pet that needs to be fetched"
required: true
type: "integer"
maximum: 10.0
minimum: 1.0
format: "int64"
responses:
"200":
description: "successful operation"
schema:
$ref: "#/definitions/Order"
"400":
description: "Invalid ID supplied"
"404":
description: "Order not found"
delete:
tags:
- "store"
summary: "Delete purchase order by ID"
description: "For valid response try integer IDs with positive integer value. Negative or non-integer values will generate API errors"
operationId: "deleteOrder"
produces:
- "application/xml"
- "application/json"
parameters:
- name: "orderId"
in: "path"
description: "ID of the order that needs to be deleted"
required: true
type: "integer"
minimum: 1.0
format: "int64"
responses:
"400":
description: "Invalid ID supplied"
"404":
description: "Order not found"
/user:
post:
tags:
- "user"
summary: "Create user"
description: "This can only be done by the logged in user."
operationId: "createUser"
produces:
- "application/xml"
- "application/json"
parameters:
- in: "body"
name: "body"
description: "Created user object"
required: true
schema:
$ref: "#/definitions/User"
responses:
default:
description: "successful operation"
/user/createWithArray:
post:
tags:
- "user"
summary: "Creates list of users with given input array"
description: ""
operationId: "createUsersWithArrayInput"
produces:
- "application/xml"
- "application/json"
parameters:
- in: "body"
name: "body"
description: "List of user object"
required: true
schema:
type: "array"
items:
$ref: "#/definitions/User"
responses:
default:
description: "successful operation"
/user/createWithList:
post:
tags:
- "user"
summary: "Creates list of users with given input array"
description: ""
operationId: "createUsersWithListInput"
produces:
- "application/xml"
- "application/json"
parameters:
- in: "body"
name: "body"
description: "List of user object"
required: true
schema:
type: "array"
items:
$ref: "#/definitions/User"
responses:
default:
description: "successful operation"
/user/login:
get:
tags:
- "user"
summary: "Logs user into the system"
description: ""
operationId: "loginUser"
produces:
- "application/xml"
- "application/json"
parameters:
- name: "username"
in: "query"
description: "The user name for login"
required: true
type: "string"
- name: "password"
in: "query"
description: "The password for login in clear text"
required: true
type: "string"
responses:
"200":
description: "successful operation"
schema:
type: "string"
headers:
X-Rate-Limit:
type: "integer"
format: "int32"
description: "calls per hour allowed by the user"
X-Expires-After:
type: "string"
format: "date-time"
description: "date in UTC when token expires"
"400":
description: "Invalid username/password supplied"
/user/logout:
get:
tags:
- "user"
summary: "Logs out current logged in user session"
description: ""
operationId: "logoutUser"
produces:
- "application/xml"
- "application/json"
parameters: []
responses:
default:
description: "successful operation"
/user/{username}:
get:
tags:
- "user"
summary: "Get user by user name"
description: ""
operationId: "getUserByName"
produces:
- "application/xml"
- "application/json"
parameters:
- name: "username"
in: "path"
description: "The name that needs to be fetched. Use user1 for testing. "
required: true
type: "string"
responses:
"200":
description: "successful operation"
schema:
$ref: "#/definitions/User"
"400":
description: "Invalid username supplied"
"404":
description: "User not found"
put:
tags:
- "user"
summary: "Updated user"
description: "This can only be done by the logged in user."
operationId: "updateUser"
produces:
- "application/xml"
- "application/json"
parameters:
- name: "username"
in: "path"
description: "name that need to be updated"
required: true
type: "string"
- in: "body"
name: "body"
description: "Updated user object"
required: true
schema:
$ref: "#/definitions/User"
responses:
"400":
description: "Invalid user supplied"
"404":
description: "User not found"
delete:
tags:
- "user"
summary: "Delete user"
description: "This can only be done by the logged in user."
operationId: "deleteUser"
produces:
- "application/xml"
- "application/json"
parameters:
- name: "username"
in: "path"
description: "The name that needs to be deleted"
required: true
type: "string"
responses:
"400":
description: "Invalid username supplied"
"404":
description: "User not found"
securityDefinitions:
petstore_auth:
type: "oauth2"
authorizationUrl: "http://petstore.swagger.io/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"
definitions:
Order:
type: "object"
properties:
id:
type: "integer"
format: "int64"
petId:
type: "integer"
format: "int64"
quantity:
type: "integer"
format: "int32"
shipDate:
type: "string"
format: "date-time"
status:
type: "string"
description: "Order Status"
enum:
- "placed"
- "approved"
- "delivered"
complete:
type: "boolean"
default: false
xml:
name: "Order"
Category:
type: "object"
properties:
id:
type: "integer"
format: "int64"
name:
type: "string"
xml:
name: "Category"
User:
type: "object"
properties:
id:
type: "integer"
format: "int64"
username:
type: "string"
firstName:
type: "string"
lastName:
type: "string"
email:
type: "string"
password:
type: "string"
phone:
type: "string"
userStatus:
type: "integer"
format: "int32"
description: "User Status"
xml:
name: "User"
Tag:
type: "object"
properties:
id:
type: "integer"
format: "int64"
name:
type: "string"
xml:
name: "Tag"
Pet:
type: "object"
required:
- "name"
- "photoUrls"
properties:
id:
type: "integer"
format: "int64"
category:
$ref: "#/definitions/Category"
name:
type: "string"
example: "doggie"
photoUrls:
type: "array"
xml:
name: "photoUrl"
wrapped: true
items:
type: "string"
tags:
type: "array"
xml:
name: "tag"
wrapped: true
items:
$ref: "#/definitions/Tag"
status:
type: "string"
description: "pet status in the store"
enum:
- "available"
- "pending"
- "sold"
xml:
name: "Pet"
ApiResponse:
type: "object"
properties:
code:
type: "integer"
format: "int32"
type:
type: "string"
message:
type: "string"
externalDocs:
description: "Find out more about Swagger"
url: "http://swagger.io"

Payload field validation in WSO2 API Manager

I've written a swagger and imported the same which will be validating the length of mobile number which should take 10 digits and also an input type which should accept only 1 Character as input or else it should throw an Error. But the message was going from APIM to ESB fairly. Should I've to make any more changes in API Manager or Code. Please suggest,
swagger: "2.0"
info:
version: v1.0.0
title: TestValidation
description: "This API to Test length Validation\n\n\nSupported operations :\n\n1. validation"
schemes:
- https
- http
consumes:
- application/json
produces:
- application/json
paths:
/validation:
post:
summary: dfgdf
description: fghfg
parameters:
- in: body
name: Payload
description: Request Body
required: false
schema:
$ref: "#/definitions/validation-request"
responses:
"200":
description: OK
schema:
$ref: "#/definitions/validation-response"
"400":
schema:
$ref: "#/definitions/TestValidation-api-error"
description: Bad Request. Invalid request or validation error.
"415":
schema:
$ref: "#/definitions/TestValidation-api-error"
description: Unsupported Media Type. The entity of the request was in a not supported format.
"500":
schema:
$ref: "#/definitions/TestValidation-api-error"
description: Internal Server Error
produces:
- application/json
consumes:
- application/json
x-auth-type: "Application & Application User"
x-throttling-tier: Unlimited
definitions:
validation-request:
type: object
properties:
MobileNum:
format: int64
type: number
minLength: 10
maxLength: 10
inputType:
type: string
minLength: 1
maxLength: 1
validation-response:
type: object
properties:
response:
type: object
TestValidation-api-error:
title: Error object returned with HTTP status
type: object
properties:
fault:
type: object
properties:
code:
format: int64
type: integer
type:
type: string
message:
description: Error message.
type: string
description:
description: A detail description about the error message.
type: string
required:
- code
- message
This feature is available in APIM 3.0.0. You have to enable it for each API you want it.
Here is the doc.
https://apim.docs.wso2.com/en/3.0.0/Learn/APISecurity/APIRequestResponseSchemaValidation/json-schema-validator/