Unable to connect a go-swagger parameter to a route - swagger

I have the following go-swagger annotation:
// swagger:parameters callbackReg
type registrationParms struct {
// Description of callback.
// in: query
// required: true
callback string
}
// OK indicates that the HTTP request was successful.
//
// swagger:response
type OK struct {
responseCode int
}
// BadRequest indicates that there was an error in
// the HTTP request.
//
// swagger:response
type BadRequest struct {
responseCode int
}
// swagger:route POST /eprouter/1.0/registration callbackReg
//
// Callback registration API.
//
// Registers a callback URL for unsolicited messages. A callback is registered for a given
// combination of message type (alarm, metric) and message encoding (Protobuf, XML).
//
// Schemes: http, https
//
// Responses:
// 200: OK
// 400: BadRequest
I generate the swagger YAML with swagger generate spec -o docs/swagger.yaml -w eprouter. The resulting YAML does not include the query parameter. My understanding is that the identifier callbackReg should tie the parameter structure to the route. What am I doing wrong?
The generated YAML:
info: {}
paths:
/eprouter/1.0/registration:
post:
description: |-
Registers a callback URL for unsolicited messages. A callback is registered for a given
combination of message type (alarm, metric) and message encoding (Protobuf, XML).
operationId: callbackReg
responses:
"200":
$ref: '#/responses/OK'
"400":
$ref: '#/responses/BadRequest'
schemes:
- http
- https
summary: Callback registration API.
responses:
BadRequest:
description: |-
BadRequest indicates that there was an error in
the HTTP request.
headers:
responseCode:
format: int64
type: integer
OK:
description: OK indicates that the HTTP request was successful.
headers:
responseCode:
format: int64
type: integer
swagger: "2.0"

The answer is that the values inside the parameter structures have to be exported (Capitalized).

Related

Swagger - Multiple responses with the same http status code with drf-yasg

I have endpoint that may return json or excel file:
class ReportView(GenericAPIView):
#swagger_auto_schema(
responses={
200: openapi.Schema(
type=openapi.TYPE_FILE,
title='Report.xlsx'
),
200: openapi.Schema(
type=openapi.TYPE_OBJECT,
),
}
)
def get(self, request):
if request.query_params.get('format') == 'xlsx':
return excel response
return json response
How could I define two 200-responses at the same time?
I read some and found out about oneOf:
responses:
'200':
description: Success
content:
application/json:
schema:
oneOf:
- $ref: '#/components/schemas/ResponseOne'
- $ref: '#/components/schemas/ResponseTwo'
example: # <--- Workaround for Swagger UI < 3.39.0
foo: bar
How could I implement it with drf_yasg?

Problem when displaying errors in friendly way in Zapier

I'm trying to display errors in a friendly way, but I'm always getting the errors stack trace with console logs that I want to get rid of.
The idea is to create a Lead in our platform using any source, for example, Google Sheets.
When an invalid email is provided in the lead and posted to our API, I'm getting the expected message I want to display followed by the stack trace.
My custom error message is
INVALID FORMAT for email. Object didn't pass validation for format email: as1#mail.
But this is what I'm getting:
INVALID FORMAT for email. Object didn't pass validation for format email: as1#mail. What happened: Starting POST request to https://cosmo-charon-production.herokuapp.com/v1/lead/vehicle Received 500 code from https://cosmo-charon-production.herokuapp.com/v1/lead/vehicle?api-key=gIBp04HVdTgsHShJj6bXKwjbcxXTogsh after 62ms Received content "{"code":"SCHEMA_VALIDATION_FAILED","message":"Request validation failed: Parameter (lead) failed sch" INVALID FORMAT for email. Object didn't pass validation for format email: as1#mail. Console logs:
Image showing error displayed in Zapier
I've added a middleware for ErrorHandling into afterResponse, just as one of the examples provided in Zapier docs.
The function analyzeAndParse() receives an error object from the API and returns a string with the error message translated in a friendly way
const checkForErrors = (response, z) => {
// If we get a bad status code, throw an error, using the ErrorTranslator
if (response.status >= 300) {
throw new Error(analyzeAndParse(response.json))
}
// If no errors just return original response
return response
}
This is the code that creates a Lead in our platform, making a request to our API.
function createLead (z, bundle) {
const industry = bundle.inputData.industry
// add product to request based on the inputFields
leadType[industry].addProductFields(bundle.inputData)
const requestOptions = {
url: `${baseUrl}lead/${_.kebabCase(industry)}`,
method: 'POST',
body: JSON.stringify(checkSourceForCreate(bundle.inputData)),
headers: {
'content-type': 'application/json'
}
}
return z.request(requestOptions).then((response) => {
if (response.status >= 300) {
throw new Error(analyzeAndParse(response.content))
}
const content = JSON.parse(response.content)
if (content && content.leads) {
// get only the last lead from the list of leads
content.lead = content.leads[0]
delete content.leads
}
return content
})
}
Any ideas?
Thanks!

How to send header in post request of RestBuilder using grails 3.3.9

Response response = new RestBuilder.post(finalUrl){
header: ["ticket", "getProxyTicket()",
"name", "abc",
"id", "1"
]
contentType: application/json
json data
}
I have the above code. And when I send the post request through API call, I get an exception "Proxy ticket must be sent as parameter in header". I don't know what is wrong with the code. Can anyone help me?
There are different ways to do it. This should work:
new RestBuilder().post(finalUrl){
// this will work if you want the value
// of the ticket header to be the literal "getProxyTicket()".
// if you are trying to invoke a method and you want the return
// value of that method to be the header value, remove the double
// quotes around getProxyTicket()
header "ticket", "getProxyTicket()"
header "name", "abc"
header "id", "1"
// no need to set the content type, the
// json method below will do that
// contentType: application/json
json data
}

Missing access token for authorization on Ebay Browse API

I try to search items from eBay API. Within the server.js file at my Apollo Server 2, I pass the token string by context property while instantiation (s. Doku: Apollo context argument). So every request contains the authentication HTTP header property. As a tryout, for now, I just use the fixed token string. This will be changed later if I work for the client.
server.js
import { ApolloServer } from 'apollo-server'
import schema from './schema'
const server = new ApolloServer({
schema,
context: ({ req }) => {
const token = 'Bearer v^1.1#i^1#I^3#f^0#p^1#r^0#t^H4sIAAA...' // my token
return {
...req,
headers: {
...req.headers,
// enrich the header with oauth token
authorization: token,
},
}
},
})
server.listen().then(({ url }) => console.log(`🚀 Server ready at ${url}`))
resolver method
// A map of functions which return data for the schema.
const resolvers = {
Query: {
books(root, { keyword = '' }, context) {
console.log(context.headers)
fetch(`https://api.ebay.com/buy/browse/v1/item_summary/?q=${keyword}`)
.then(response => response.json())
.then(json => console.log(json))
return []
}
}
}
The context.header contains the authorization property:
{ host: 'localhost:4000',
connection: 'keep-alive',
'content-length': '108',
accept: '*/*',
origin: 'http://localhost:4000',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
dnt: '1',
'content-type': 'application/json',
referer: 'http://localhost:4000/',
'accept-encoding': 'gzip, deflate, br',
'accept-language': 'de,en;q=0.9',
authorization: 'Bearer v^1.1#i^1#f^0#p^1#r^0#I^3#t^H4sIAAAAAAAAAOV...'
}
The JSON response contains the error with errorId 1002. It says Access token is missing in the Authorization HTTP request header.:
{ errors:
[ { errorId: 1002,
domain: 'OAuth',
category: 'REQUEST',
message: 'Missing access token',
longMessage: 'Access token is missing in the Authorization HTTP request header.' } ] }
Additionally, I use a new browser tab, enter the URL https://api.ebay.com/buy/browse/v1/item_summary/search?q=test and add the same authorization header property (I use the ModHeader chrome extension). I hit enter, the request works and I get the expected JSON.
It is confusing and I don't know what I'm doing wrong while passing the token. Does somebody have an idea?
The headers you see are the ones being sent in the request to your GraphQL server. All you've done is modified them to include the Authorization header and then included your entire request object as your context -- you're not passing any header information to the fetch call actually getting the data from eBay. Minimally, you want to do something like this:
fetch(`https://api.ebay.com/buy/browse/v1/item_summary/?q=${keyword}`, {
headers: {
Authorization: context.headers.authorization,
},
})
Also bear in mind that the fetch call should be returned inside your resolver, otherwise it won't be awaited.

How to describe this POST JSON request body in OpenAPI (Swagger)?

I have a POST request that uses the following JSON request body. How can I describe this request body using OpenAPI (Swagger)?
{
"testapi":{
"testapiContext":{
"messageId":"kkkk8",
"messageDateTime":"2014-08-17T14:07:30+0530"
},
"testapiBody":{
"cameraServiceRq":{
"osType":"android",
"deviceType":"samsung555"
}
}
}
}
So far I tried the following, but I'm stuck at defining the body schema.
swagger: "2.0"
info:
version: 1.0.0
title: get camera
license:
name: MIT
host: localhost
basePath: /test/service
schemes:
- http
consumes:
- application/json
produces:
- application/json
paths:
/getCameraParameters:
post:
summary: Create new parameters
operationId: createnew
consumes:
- application/json
- application/xml
produces:
- application/json
- application/xml
parameters:
- name: pet
in: body
description: The pet JSON you want to post
schema: # <--- What do I write here?
required: true
responses:
200:
description: "200 response"
examples:
application/json:
{
"status": "Success"
}
I want to define the input body inline, as a sample for documentation.
I made it work with:
post:
consumes:
- application/json
produces:
- application/json
- text/xml
- text/html
parameters:
- name: body
in: body
required: true
schema:
# Body schema with atomic property examples
type: object
properties:
testapi:
type: object
properties:
messageId:
type: string
example: kkkk8
messageDateTime:
type: string
example: '2014-08-17T14:07:30+0530'
testapiBody:
type: object
properties:
cameraServiceRq:
type: object
properties:
osType:
type: string
example: android
deviceType:
type: string
example: samsung555
# Alternatively, we can use a schema-level example
example:
testapi:
testapiContext:
messageId: kkkk8
messageDateTime: '2014-08-17T14:07:30+0530'
testapiBody:
cameraServiceRq:
osType: android
deviceType: samsung555
The most readable way to include a multi line scalar into YAML is by using the block literal style. This requires you to change your JSON example only by using indentation (which will be removed if you retrieve the value for the key):
.
.
produces:
- application/json
example: |
{
"testapi": {
"testapiContext": {
"messageId": "kkkk8",
"messageDateTime": "2014-08-17T14:07:30+0530"
},
"testapiBody": {
"cameraServiceRq": {
"osType": "android",
"deviceType": "samsung555"
}
}
}
}
paths:
/getCameraParameters:
.
.
(for clarity you can put an extra newline or two before the paths scalar key, they get clipped by default on the literal block style scalars.
openapi version >= 3.0.0 allows for the use of a requestBody which would allow for request body definitions outside of parameters.
In your case it would look something like this:
...
requestBody:
description: The pet JSON you want to post
required: true
content:
application/json:
schema:
type: object
properties:
testapi:
type: object
properties:
messageId:
type: string
example: kkkk8
messageDateTime:
type: string
example: '2014-08-17T14:07:30+0530'
testapiBody:
type: object
properties:
cameraServiceRq:
type: object
properties:
osType:
type: string
example: android
deviceType:
type: string
example: samsung555
example:
testapi:
testapiContext:
messageId: kkkk8
messageDateTime: '2014-08-17T14:07:30+0530'
testapiBody:
cameraServiceRq:
osType: android
deviceType: samsung555
...

Resources