I'm new to OpenAPI and I need some help to create a basic swagger file for PayPal's payment API to create a payment from our platform. Note: OAuth is already configured.
Below is a basic swagger file but I don't know where to add the paymet request information (i.e. intent, payer, transactions etc.) into:
{
"swagger": "2.0",
"info": {
"description": "this is a payment request to through PayPal",
"title": "Swagger PayPal Payment",
"version": "1.0.0"
},
"host": "api.sandbox.paypal.com",
"basePath": "/v1/payments", //
"schemes": [ "https" ],
"paths": {
"/payment":
{
"post": {
"summary": "Creates a payment"
"description": "Creates a payment request to Paypal",
"parameters": {
},
//"intent": "sale",
//"payer":
//{
// "payment_method": "paypal"
//},
//"transactions": [
// {
// "amount": {
// "total": "9.00",
// "currency": "EUR"
// }
// }
//],
"responses": {
"200": {
"description": "OK"
}
}
}
}
}
}
Testing the file on editor.swagger, I get an "OBJECT_ADDITIONAL_PROPERTIES" error on transactions, payer, and intent.
JSON payload is defined as a body parameter (parameter with in: body), and this parameter needs a schema that defines the JSON object properties.
You would typically define object schemas in the global definitions section and reference them using $ref.
Here is the YAML version for readability. To convert it to JSON, paste it into http://editor.swagger.io and use File > Download JSON.
swagger: "2.0"
info:
description: this is a payment request to through PayPal
title: Swagger PayPal Payment
version: "1.0.0"
host: api.sandbox.paypal.com
basePath: /v1/payments
schemes: [ https ]
paths:
/payment:
post:
summary: Creates a payment
description: Creates a payment request to Paypal
parameters:
- in: body
name: payment
required: true
schema:
$ref: "#/definitions/Payment" # <--------
responses:
"200":
description: OK
definitions:
# Request body object
Payment:
type: object
properties:
intent:
type: string
payer:
$ref: "#/definitions/Payer"
transactions:
type: array
items:
$ref: "#/definitions/Transaction"
Payer:
type: object
properties:
payment_method:
type: string
example: paypal
Transaction:
type: object
properties:
... # TODO
Related
I used the code to convert json data from Yarn REST API to Prometheus data type:
https://github.com/prometheus-community/json_exporter.
However, it printed errors:
level=error ts=2021-07-08T06:31:03.712Z caller=collector.go:83 msg="Failed to extract value for metric" path={.capacity} err="capacity is not found" metric="Desc{fqName: "queues_capacity", help: "information on queues", constLabels: {}, variableLabels: [type]}"
I was wondering if there is some wrong in my configuration of YAML file (such as in terms of nested json) or just the reason about the code.
my yaml config is:
metrics:
- name: queues
path: "{ .scheduler.schedulerInfo.queues.queue }"
help: information on queues
type: object
labels:
type: '{.type}'
values:
capacity: '{.capacity}'
and part of the json file is:
{
"scheduler": {
"schedulerInfo": {
"type": "capacityScheduler",
"capacity": 100,
"usedCapacity": 1.0526316,
"maxCapacity": 100,
"queueName": "root",
"queues": {
"queue": [
{
"type": "capacitySchedulerLeafQueueInfo",
"capacity": 10,
"usedCapacity": 10.526316,
"maxCapacity": 100,
use [*] to get all object first, so it should be:
path: "{ .scheduler.schedulerInfo.queues.queue[*] }"
according to this: https://kubernetes.io/docs/reference/kubectl/jsonpath/
We have used IoT agent -1.14.0 version from docker hub.
We have given the service and servicepath as follows
fiware-service:testiotagent
fiware-servicepath:/
Device registration payload :
{
"devices": [
{
"device_id":"Motion-10",
"entity_name":"urn:ngsi-ld:SENSOR:Motion-10",
"entity_type":"SENSOR",
"transport": "MQTT",
"attributes": [
{"object_id": "s", "name": "state", "type":"Text"},
{"object_id": "l", "name": "luminosity", "type":"Integer",
"metadata":{ "unitCode":{"type": "Text", "value" :"CAL"}
}
}
]
}
]
}
As per iotagent node lib version 2.12.0 ,IoT agent json -1.14.0 version should support the metadata in device provisioned attributes. But still facing issue.
When we try to provision the above device we are getting the below error:
{
"name": "WRONG_SYNTAX",
"message": "Wrong syntax in request: Errors found validating request."
}
I found that iotagent-node-lib have the schema to validate against device registration payload
https://github.com/telefonicaid/iotagent-node-lib/blob/master/lib/templates/createDevice.json
In this json schema there is no metadata schema mentioned in attributes.
I have followed the below steps for metadata in Entity level:
I have removed the metadata in IoT agent
Updated the entity 'urn:ngsi-ld:SENSOR:Motion-10' as below
{
"id":"urn:ngsi-ld:SENSOR:Motion-10",
"type":"SENSOR",
"luminosity":{
"type":"Integer",
"value":"0",
"metadata":{ "unitCode":{"type": "Text", "value" :"CAL"}
}
}
Tried to send measurement and metadata got overriden and got the empty metadata
{
"id":"urn:ngsi-ld:SENSOR:Motion-10",
"type":"SENSOR",
"luminosity":{
"type":"Integer",
"value":"15",
"metadata":{}
}
}
Is it due to the fix given for issue 1788 in fiware-orion ,https://github.com/telefonicaid/fiware-orion/issues?q=1788.
Need some qucik confirmation and help from Fiware experts to overcome this issue, it is very much appreciated.
The templates checking a valid provisioning request currently does not accept the metadata attribute. There is an outstanding PR for this. At the moment you would be better off defining the Entities with the metadata in a config.js file instead.
e.g.:
iotAgentConfig = {
contextBroker: {
host: '192.168.1.1',
port: '1026',
ngsiVersion: 'v2'
},
server: {
port: 4041
},
types: {
'WeatherStation': {
commands: [],
type: 'WeatherStation',
lazy: [],
active: [
{
object_id: 'p',
name: 'pressure',
type: 'Hgmm'
},
{
object_id: 'h',
name: 'humidity',
type: 'Percentage',
entity_name: 'Higro2000',
entity_type: 'Higrometer',
metadata:{
unitCode:{
type: "Text", value :"Hgmm"
}
}
}
]
},
....etc
Let's say we have an example json swagger spec:
{
"swagger": "2.0",
"info": {
"version": "1.0.0",
"title": "Some API"
},
"basePath": "/api/v1",
"consumes": [
"application/json"
],
"produces": [
"application/json",
"text/csv"
],
"paths": {
"/some/endpoint": {
"get": {
"parameters": [
{
"in": "body",
"name": "body",
"required": false,
"schema": {
"$ref": "#/definitions/BodyParamsDefinition"
}
}
],
"responses": {
"200": { ?? } ...
There are two content types that can be produced:
application/json
text/csv
Default response for GET /some/endpoint is a csv file, but if the format query param is used like this /some/endpoint?format=json, the response would be in json format.
I have trouble finding how should I finish my specification with proper responses.
When I use this approach: https://swagger.io/docs/specification/describing-responses/ i get a validation error: ...get.responses['200'] should NOT have additional properties
You are almost there, you just need to define a schema for the response. This schema defines the response structure for all content types associated with this status code.
For example, if the operation returns this JSON:
[
{
"petType": "dog",
"name": "Fluffy"
},
{
"petType": "cat",
"name": "Crookshanks"
}
]
and this CSV:
petType,name
dog,Fluffy
cat,Crookshanks
you would use:
# YAML
responses:
200:
description: OK
schema:
type: array
items:
type: object
properties:
petType:
type: string
name:
type: string
More info: Describing Responses
In OpenAPI 3.0, content type definitions were improved and schemas can vary by content type:
openapi: 3.0.0
...
paths:
/some/endpoint:
get:
responses:
'200':
description: OK
content:
# JSON data is an object
application/json:
schema:
type: object
properties:
message:
type: string
# CSV data is a string of text
text/csv:
schema:
type: string
Default response for GET /some/endpoint is a csv file, but if the format query param is used like this /some/endpoint?format=json, the response would be in json format.
There's currently no way to map specific responses to specific operation parameters, but there are several related proposals in the OpenAPI Specification repository:
Accommodate legacy APIs by allowing query parameters in the path
Querystring in Path Specification
Support an operation to have multiple specifications per path
Overloading
I have the following resource on my CloudFormation template to create a rule to run a Lambda function, from the AWS documentation:
"ScheduledRule": {
"Type": "AWS::Events::Rule",
"Properties": {
"Description": "ScheduledRule",
"ScheduleExpression": "rate(5 minutes)",
"State": "ENABLED",
"Targets": [{
"Arn": { "Fn::GetAtt": ["myLambda", "Arn"] },
"Id": "TargetFunctionV1"
}]
}
}
I would like to specify the Input:
{
"Arn" : String,
"Id" : String,
"Input" : String,
"InputPath" : String
}
and Input is a JSON-formatted text string that is passed to the target. This value overrides the matched event.
I would like my JSON formatted text to be:
{
"mykey1": "Some Value"
}
I do not know how to specify it in the Input, when I put:
"ScheduledRule": {
"Type": "AWS::Events::Rule",
"Properties": {
"Description": "ScheduledRule",
"ScheduleExpression": "rate(5 minutes)",
"State": "ENABLED",
"Targets": [{
"Arn": { "Fn::GetAtt": ["myLambda", "Arn"] },
"Id": "TargetFunctionV1",
"Input": { "mykey1": "Some Value" }
}]
}
}
I will get error:
Value of property Input must be of type String
How should I specify it correctly?
I would use YAML as it is easier and more readable:
Input:
!Sub |
{
mykey1: "${myKey}"
}
Found out the answer myself:
"Input": "{ \"test\" : \"value11\", \"test2\" : \"value22\"}"
Hope it helps someone else.
Update:
You basically use the result of JSON.Stringify() to get the string into "Input" field. Use online JSON.Stringify() like https://onlinetexttools.com/json-stringify-text
I wanted to expand on #Pau's answer. Basically if you use the | to say that the whole block below is to be treated as a raw string.
If you need to replace any variable in the JSON then you can use Sub, but if you don't have any variables, then you don't need Sub. An example would be:
Input:|
{
"jsonVar":"jsonVal",
"jsonVar2" : "jsonVal2"
}
You can later do JSON.parse(<input-variable>) to get the JSON object.
NOTE: Don't put commas at the end of the variables in JSON, if there is no next variable. Example :
Input:|
{
"jsonVar":"jsonVal",
"jsonVar2" : "jsonVal2",
}
This will cause JSON parsing errors.
If you are writing your CloudFormation scripts in yaml and finding it difficult to use a JSON string (such as a policy doc) the easiest way is to convert your JSON into yaml using an online converter
ApiGatewayRestApi:
Type: AWS::ApiGateway::RestApi
Properties:
Description: API Gateway for some API
EndpointConfiguration:
Types:
- PRIVATE
Name: MyAPIGateway
Policy: <Policy Doc >
Lets say the policy doc is as follows.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": "execute-api:Invoke",
"Resource": "arn:aws:execute-api:ap-southeast-2:something/*",
"Condition": {
"ForAnyValue:StringEquals": {
"aws:sourceVpce": "vpce-abcd"
}
}
}
]
}
Using the converter you can convert the JSON into an identical yaml and use as follows.
ApiGatewayRestApi:
Type: AWS::ApiGateway::RestApi
Properties:
Description: API Gateway for some API
EndpointConfiguration:
Types:
- PRIVATE
Name: MyAPIGateway
Policy:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal: "*"
Action: execute-api:Invoke
Resource: arn:aws:execute-api:ap-southeast-2:something/*
Condition:
ForAnyValue:StringEquals:
aws:sourceVpce: vpce-abcd
Here's my similar YAML code for the "input" line. It took me all day to figure out the syntax so I'm hoping this might help someone in the future.
Input: "{\"action\":[\"configure\"],\"mode\":[\"ec2\"],\"optionalConfigurationSource\":[\"ssm\"],\"optionalConfigurationLocation\":[\"AmazonCloudWatch-Baseline-Windows\"],\"optionalRestart\":[\"yes\"]}"
I have the following files
user.json
"user": {
"id": 1,
"name": "nameuser",
"online": true,
"profile": {
"photo": "",
"validated": true,
"popular": true,
"suspect": false,
"moderator": false,
"age": "22 ani",
"gender_id": "M"
}
}
profile.raml
displayName: Profile
get:
description: Get profile data
queryParameters:
userId:
description: The user id for which we are requesting the profile data
type: integer
required: true
responses:
200:
body:
application/json:
example: |
{
"user": !include user.json,
"details": {
"friend": true
}
}
The user json is present in more examples and I want to reuse it.
I'm using raml2html and it compiles it to
so how do I do this ?
I have used parameters successfully in the past. You will not be able to put a parameter inside an included file because RAML views all included files as strings. But you can do something like this in your profile.raml:
example: |
{
"user": <<userItem>>,
"details": {
"friend": true
}
}
The RAML 200 Tutorial has a good explanation and code examples (see snippets below) on how to declare parameters and them pass them in. I highly recommend reading the entire tutorial though.
resourceTypes:
- collection:
description: Collection of available <<resourcePathName>> in Jukebox.
get:
description: Get a list of <<resourcePathName>>.
responses:
200:
body:
application/json:
example: |
<<exampleCollection>>
/songs:
type:
collection:
exampleCollection: !include jukebox-include-songs.sample