Static API docs with source2swagger - swagger

source2swagger generates a swagger spec with all apis in one json file. Can swagger-ui actually use that? When I explore the generated json file with swagger-ui, it tries to read the api descriptions from their paths in the spec, instead of using the descriptions/operations right there in the single json file.

Swagger-UI will handle putting all the json in one file. I'm not sure yet if there can be multiple top-level resource listings though.
Here's a working example:
{"basePath":"http://localhost:3001/", "resourcePath":"/", "swaggerVersion":"1.1", "apiVersion":"1.0", "apis":[
{
"path":"/pay",
"format":"json",
"description":"Create a transaction with the given amount and token.",
"operations":[
{
"httpMethod":"GET",
"tags":["production"],
"nickname":"pay",
"deprecated":false,
"summary":"Create a transaction with the given amount and token.",
"parameters":[
{
"name":"token",
"description":"The token representing the pay card",
"dataType":"string",
"allowMultiple":false,
"required":true,
"paramType":"query"
},
{
"name":"amount",
"description":"The amount to pay",
"dataType":"string",
"allowMultiple":false,
"required":true,
"paramType":"query"
}
]
}
]
},
{
"path":"/customer",
"format":"json",
"description":"Create an HTML form for adding a customer.",
"operations":[
{
"httpMethod":"GET",
"tags":["production"],
"nickname":"createCustomerForm",
"deprecated":false,
"summary":"Create an HTML form for adding a customer.",
"parameters":[
{
"name":"customerId",
"description":"Your customer id",
"dataType":"string",
"allowMultiple":false,
"required":true,
"paramType":"query"
}
]
}
]
},
{
"path":"/customer/{customerId}",
"format":"json",
"description":"Delete the customer info for given id.",
"operations":[
{
"httpMethod":"DELETE",
"tags":["production"],
"nickname":"deleteCustomer",
"deprecated":false,
"summary":"Delete the customer info for given id.",
"parameters":[
{
"name":"customerId",
"description":"the customer id to delete",
"dataType":"string",
"allowMultiple":false,
"required":true,
"paramType":"path"
}
]
}
]
},
{
"path":"/card",
"format":"json",
"description":"Create an HTML form for adding a credit card.",
"operations":[
{
"httpMethod":"GET",
"tags":["production"],
"nickname":"createCardForm",
"deprecated":false,
"summary":"Create an HTML form for the given customer to add a credit card.",
"parameters":[
{
"name":"customerId",
"description":"Your customer id",
"dataType":"string",
"allowMultiple":false,
"required":true,
"paramType":"query"
}
]
}
]
},
{
"path":"/card/{token}",
"format":"json",
"description":"Delete a card record by token.",
"operations":[
{
"httpMethod":"DELETE",
"tags":["production"],
"nickname":"deleteCard",
"deprecated":false,
"summary":"Delete the card info for given token.",
"parameters":[
{
"name":"token",
"description":"the token to delete",
"dataType":"string",
"allowMultiple":false,
"required":true,
"paramType":"path"
}
]
}
]
}
]}

Related

ADP API Update Worker Information

I am trying to make updates within the ADP Worker API, though I keep getting "403: Invalid Scope" for the error. I am using this reference guide, specifically the People > Personal Information > Personal Profile > Contact > Add Home Phone section.
I can interact with the API through GET requests, though I am unable to POST. I am using the URL:
https://api.adp.com/events/hr/v1/worker.personal-communication.landline.add
Body Payload:
{
"events": [
{
"data": {
"eventContext": {
"worker": {
"associateOID": "exampleID123123"
}
},
"transform": {
"worker": {
"person": {
"communication": {
"landline": {
"areaDialing": "240",
"dialNumber": "4567896"
}
}
}
}
}
},
"links": []
}
]
}
Response:
{
"response": {
"responseCode": 403,
"methodCode": "POST",
"resourceUri": {
"href": "/events/hr/v1/worker.personal-communication.landline.add"
},
"serverRequestDateTime": "2021-09-09T18:26:44.607Z",
"applicationCode": {
"code": 403,
"typeCode": "error",
"message": "Invalid Scope"
},
"client_ip_adddress": "xxx.xx.xxx.xxxx",
"adp-correlationID": "xxxxxxxxx-xxxxxxxxxxx-xxxxxxxxxx"
}
}
Any suggestions? Thank you in advance!
After some searching, I believe the answer to my initial question is that we are required to contact our ADP representative to add the ability to hit the Event API. We only had access to the Worker API, which allowed successful calls previously.

Invalid Reference Id : Line.SalesItemLineDetail.ItemRef

I have tried to create sales receipt in quickbook using quickbook api. My most of sales receipt has successfully created at quick book without any issue. But quickbook api throw exception for one order. I have got below error:
{
"Fault": {
"Error": [
{
"Message": "Invalid Reference Id",
"Detail": "Invalid Reference Id : Line.SalesItemLineDetail.ItemRef",
"code": "2500",
"element": "Line.SalesItemLineDetail.ItemRef"
}
],
"type": "ValidationFault"
},
"time": "2017-05-04T03:32:18.942-07:00"
}
Below are json that I have tried with API :
{
"SalesReceiptEx":null,
"AutoDocNumber":null,
"CustomerRef":{
"name":"Alexander",
"type":null,
"value":"325"
},
"CustomerMemo":null,
"BillAddr":{
"Id":"1",
"Line1":"Alexander Kryukov",
"Line2":"22 Chester Terrace",
"Line3":"London",
"Line4":"United Kingdom,GB",
"Line5":"NW1 4ND",
"City":null,
"Country":null,
"CountryCode":null,
"CountrySubDivisionCode":null,
"PostalCode":null,
"PostalCodeSuffix":null,
"Lat":null,
"Long":null,
"Tag":null,
"Note":null
},
"ShipAddr":{
"Id":"2",
"Line1":"Alexander Kryukov",
"Line2":"22 Chester Terrace",
"Line3":null,
"Line4":null,
"Line5":null,
"City":"London",
"Country":"United Kingdom",
"CountryCode":null,
"CountrySubDivisionCode":"GB",
"PostalCode":"NW1 4ND",
"PostalCodeSuffix":null,
"Lat":null,
"Long":null,
"Tag":null,
"Note":null
},
"RemitToRef":null,
"ClassRef":null,
"SalesTermRef":null,
"DueDate":null,
"SalesRepRef":null,
"PONumber":null,
"FOB":null,
"ShipMethodRef":null,
"ShipDate":null,
"TrackingNum":null,
"GlobalTaxCalculation":null,
"TotalAmt":"136.90000",
"HomeTotalAmt":null,
"ApplyTaxAfterDiscount":null,
"TemplateRef":null,
"PrintStatus":null,
"EmailStatus":null,
"BillEmail":{
"Id":null,
"Address":"sash_300#hotmail.com",
"Default":null,
"Tag":null
},
"ARAccountRef":null,
"Balance":null,
"HomeBalance":null,
"FinanceCharge":null,
"PaymentMethodRef":null,
"PaymentRefNum":null,
"PaymentType":null,
"CheckPayment":null,
"CreditCardPayment":null,
"DepositToAccountRef":{
"name":"Business Bank Account HSBC",
"type":null,
"value":58
},
"DeliveryInfo":null,
"DiscountRate":null,
"DiscountAmt":null,
"GovtTxnRefIdentifier":null,
"DocNumber":1163080716,
"TxnDate":"2017-05-04",
"DepartmentRef":null,
"CurrencyRef":null,
"ExchangeRate":null,
"PrivateNote":null,
"TxnStatus":null,
"LinkedTxn":null,
"Line":[
{
"Id":1,
"LineNum":1,
"Description":"Flowery Floater Birthday Number",
"Amount":"43.29167",
"LinkedTxn":null,
"DetailType":"SalesItemLineDetail",
"PaymentLineDetail":null,
"DiscountLineDetail":null,
"TaxLineDetail":null,
"SalesItemLineDetail":{
"ServiceDate":null,
"TaxInclusiveAmt":null,
"DiscountRate":null,
"DiscountAmt":null,
"SalesItemLineDetailEx":null,
"ItemRef":{
"name":"Flowery Floater Birthday Number",
"type":null,
"value":"1"
},
"ClassRef":null,
"UnitPrice":"43.29167",
"RatePercent":null,
"PriceLevelRef":null,
"MarkupInfo":null,
"Qty":"1",
"UOMRef":null,
"ItemAccountRef":null,
"InventorySiteRef":null,
"TaxCodeRef":{
"name":null,
"type":null,
"value":2
}
},
"DescriptionLineDetail":null,
"ItemBasedExpenseLineDetail":null,
"AccountBasedExpenseLineDetail":null,
"DepositLineDetail":null,
"PurchaseOrderItemLineDetail":null,
"ItemReceiptLineDetail":null,
"JournalEntryLineDetail":null,
"GroupLineDetail":null,
"SubTotalLineDetail":null,
"TDSLineDetail":null,
"CustomField":null,
"LineEx":null
},
{
"Id":2,
"LineNum":2,
"Description":"Custom Product",
"Amount":"37.50000",
"LinkedTxn":null,
"DetailType":"SalesItemLineDetail",
"PaymentLineDetail":null,
"DiscountLineDetail":null,
"TaxLineDetail":null,
"SalesItemLineDetail":{
"ServiceDate":null,
"TaxInclusiveAmt":null,
"DiscountRate":null,
"DiscountAmt":null,
"SalesItemLineDetailEx":null,
"ItemRef":{
"name":"Custom Product",
"type":null,
"value":"10"
},
"ClassRef":null,
"UnitPrice":"3.75000",
"RatePercent":null,
"PriceLevelRef":null,
"MarkupInfo":null,
"Qty":"10",
"UOMRef":null,
"ItemAccountRef":null,
"InventorySiteRef":null,
"TaxCodeRef":{
"name":null,
"type":null,
"value":2
}
},
"DescriptionLineDetail":null,
"ItemBasedExpenseLineDetail":null,
"AccountBasedExpenseLineDetail":null,
"DepositLineDetail":null,
"PurchaseOrderItemLineDetail":null,
"ItemReceiptLineDetail":null,
"JournalEntryLineDetail":null,
"GroupLineDetail":null,
"SubTotalLineDetail":null,
"TDSLineDetail":null,
"CustomField":null,
"LineEx":null
},
{
"Id":3,
"LineNum":3,
"Description":"Additional Delivery Charge",
"Amount":"30.00000",
"LinkedTxn":null,
"DetailType":"SalesItemLineDetail",
"PaymentLineDetail":null,
"DiscountLineDetail":null,
"TaxLineDetail":null,
"SalesItemLineDetail":{
"ServiceDate":null,
"TaxInclusiveAmt":null,
"DiscountRate":null,
"DiscountAmt":null,
"SalesItemLineDetailEx":null,
"ItemRef":{
"name":"Additional Delivery Charge",
"type":null,
"value":"1"
},
"ClassRef":null,
"UnitPrice":"30.00000",
"RatePercent":null,
"PriceLevelRef":null,
"MarkupInfo":null,
"Qty":"1",
"UOMRef":null,
"ItemAccountRef":null,
"InventorySiteRef":null,
"TaxCodeRef":{
"name":null,
"type":null,
"value":2
}
},
"DescriptionLineDetail":null,
"ItemBasedExpenseLineDetail":null,
"AccountBasedExpenseLineDetail":null,
"DepositLineDetail":null,
"PurchaseOrderItemLineDetail":null,
"ItemReceiptLineDetail":null,
"JournalEntryLineDetail":null,
"GroupLineDetail":null,
"SubTotalLineDetail":null,
"TDSLineDetail":null,
"CustomField":null,
"LineEx":null
},
{
"Id":4,
"LineNum":4,
"Description":"Shipping Cost",
"Amount":"3.29167",
"LinkedTxn":null,
"DetailType":"SalesItemLineDetail",
"PaymentLineDetail":null,
"DiscountLineDetail":null,
"TaxLineDetail":null,
"SalesItemLineDetail":{
"ServiceDate":null,
"TaxInclusiveAmt":null,
"DiscountRate":null,
"DiscountAmt":null,
"SalesItemLineDetailEx":null,
"ItemRef":{
"name":"Shipping Cost",
"type":null,
"value":"1"
},
"ClassRef":null,
"UnitPrice":"3.29167",
"RatePercent":null,
"PriceLevelRef":null,
"MarkupInfo":null,
"Qty":"1",
"UOMRef":null,
"ItemAccountRef":null,
"InventorySiteRef":null,
"TaxCodeRef":{
"name":null,
"type":null,
"value":2
}
},
"DescriptionLineDetail":null,
"ItemBasedExpenseLineDetail":null,
"AccountBasedExpenseLineDetail":null,
"DepositLineDetail":null,
"PurchaseOrderItemLineDetail":null,
"ItemReceiptLineDetail":null,
"JournalEntryLineDetail":null,
"GroupLineDetail":null,
"SubTotalLineDetail":null,
"TDSLineDetail":null,
"CustomField":null,
"LineEx":null
}
],
"TxnTaxDetail":null,
"TxnSource":null,
"TaxFormType":null,
"TaxFormNum":null,
"TransactionLocationType":null,
"Id":null,
"SyncToken":null,
"MetaData":null,
"CustomField":null,
"AttachableRef":null,
"domain":null,
"status":null,
"sparse":null
}
Could anyone suggest, what is actual problem with this request?
The error message indicates exactly what the problem is:
"Message": "Invalid Reference Id",
"Detail": "Invalid Reference Id : Line.SalesItemLineDetail.ItemRef",
"code": "2500",
"element": "Line.SalesItemLineDetail.ItemRef"
Based on your request, it looks like you're just inventing these values, rather than actually querying these from QuickBooks.
I'm assuming this because in one place your item is called one thing, and in another it's called something totally different:
"ItemRef":{
"name":"Shipping Cost",
"type":null,
"value":"1"
},
Even though the Id values are identical (1) in both cases:
"ItemRef":{
"name":"Additional Delivery Charge",
"type":null,
"value":"1"
},
You can't just invent these numbers. They are Id values that you have to query from Intuit.
https://developer.intuit.com/docs/api/accounting/item
Query them by doing:
SELECT * FROM Item
I got this error when trying to submit an invoice line item with an ID outside the range of available IDs in the QuickBooks Sandbox.
For example, my production app has ~50 categories and the Sandbox only has ~20, so trying to use ID 40 in the Sandbox caused this error.
To resolve the issue I simply reduced the ID number for testing.

Firebase iOS - Query with one part of the compound key

In my Firebase database I use a compound key as the ID for one-to-one conversations in the following format 'UID1_UID2' sorted lexicographically.
When I want to load all conversations via the iOS client for a particular user (UID1) how can I query Firebase when the compound key consists of two combined user IDs.
queryStartingAt("UID1_").queryEndingAt("UID1_")
will return all conversations UID1_ started.
You should be structuring your data as
conversation: UID1_UID2
Compound keys are not that great of an idea. Please consult this part of the documentation that explains how to best model a chat / conversation structure.
Relevant excerpt demonstrating how to structure data for chats:
{
// Chats contains only meta info about each conversation
// stored under the chats's unique ID
"chats": {
"one": {
"title": "Historical Tech Pioneers",
"lastMessage": "ghopper: Relay malfunction found. Cause: moth.",
"timestamp": 1459361875666
},
"two": { ... },
"three": { ... }
},
// Conversation members are easily accessible
// and stored by chat conversation ID
"members": {
// we'll talk about indices like this below
"one": {
"ghopper": true,
"alovelace": true,
"eclarke": true
},
"two": { ... },
"three": { ... }
},
// Messages are separate from data we may want to iterate quickly
// but still easily paginated and queried, and organized by chat
// conversation ID
"messages": {
"one": {
"m1": {
"name": "eclarke",
"message": "The relay seems to be malfunctioning.",
"timestamp": 1459361875337
},
"m2": { ... },
"m3": { ... }
},
"two": { ... },
"three": { ... }
}
}

Swagger API which is having query string

I want to deploy an API which is having query string.This is the API
v1/products?q=circuit breaker&locale=en-GB&pageSize=8&pageNo=1&project=GLOBAL
Here is how i am implementing
"/v1/products?q={searchText}&locale={ctrCode}&pageSize={pageSize}&pageNo={pageNo}&project={project}&country={country}":{
"get":{
"tags":[
"Search Text"
],
"summary":"Get Products by searching text, countrycode, page number, pagesize, project and country(optional)",
"description":"Get Products by searching text, countrycode, page number, pagesize, project and country(optional)",
"operationId":"getProductName",
"produces":[
"application/json",
"application/xml"
],
"parameters":[
{
"name":"searchText",
"in":"path",
"description":"The Product that needs to be fetched",
"required":true,
"type":"string"
},
{
"name":"ctrCode",
"in":"path",
"description":"The Product locale needs to be fetched. Example=en-GB, fr-FR, etc.",
"required":true,
"type":"string"
},
{
"name":"pageSize",
"in":"path",
"description":"The Product PageSize that needs to be fetched. Example=10, 20 etc.",
"required":true,
"type":"number"
},
{
"name":"pageNo",
"in":"path",
"description":"The Product pageNo that needs to be fetched. Example=1,2 etc.",
"required":true,
"type":"number"
},
{
"name":"project",
"in":"path",
"description":"The Project that needs to be fetched. Example=Mypact, DSL etc.",
"required":true,
"type":"string"
},
{
"name":"country",
"in":"header",
"description":"The Country that needs to be fetched. Example=France, India etc.",
"required":false,
"type":"string"
}
],
"responses":{
"200":{
"description":"successful operation",
"schema":{
"$ref":"#/definitions/Products"
}
},
"400":{
"description":"Invalid Product_id supplied"
},
"404":{
"description":"Product not found"
}
}
}
}
The country is optional parameter in this. I want the URL should display country only when if user enter some value, else it should not be displayed in the URL.
You can't describe query parameters as part of the path in Swagger. You have to declare those explicitly as query parameters.
"/v1/products":{
"get":{
"tags":[
"Search Text"
],
"summary":"Get Products by searching text, countrycode, page number, pagesize, project and country(optional)",
"description":"Get Products by searching text, countrycode, page number, pagesize, project and country(optional)",
"operationId":"getProductName",
"produces":[
"application/json",
"application/xml"
],
"parameters":[
{
"name":"searchText",
"in":"query",
"description":"The Product that needs to be fetched",
"required":true,
"type":"string"
},
{
"name":"ctrCode",
"in":"query",
"description":"The Product locale needs to be fetched. Example=en-GB, fr-FR, etc.",
"required":true,
"type":"string"
},
{
"name":"pageSize",
"in":"query",
"description":"The Product PageSize that needs to be fetched. Example=10, 20 etc.",
"required":true,
"type":"number"
},
{
"name":"pageNo",
"in":"query",
"description":"The Product pageNo that needs to be fetched. Example=1,2 etc.",
"required":true,
"type":"number"
},
{
"name":"project",
"in":"query",
"description":"The Project that needs to be fetched. Example=Mypact, DSL etc.",
"required":true,
"type":"string"
},
{
"name":"country",
"in":"query",
"description":"The Country that needs to be fetched. Example=France, India etc.",
"required":false,
"type":"string"
}
],
"responses":{
"200":{
"description":"successful operation",
"schema":{
"$ref":"#/definitions/Products"
}
},
"400":{
"description":"Invalid Product_id supplied"
},
"404":{
"description":"Product not found"
}
}
}
}
Your IN parameter needs to be "query" not "path"
This should work:
"parameters": [
{
"name":"country",
"in":"query",
"description":"The Country that needs to be fetched. Example=France, India etc.",
"required":false,
"type":"string"
}
]
In editor.swagger.io you can do it like that:
no params in your routing
params' attribute 'in' has to be 'query'
/v1/products:
get:
tags:
- Search Text
summary: Get Products by searching text, countrycode, page number, pagesize, project and country(optional)
description: Get Products by searching text, countrycode, page number, pagesize, project and country(optional)
operationId: getProductName
parameters:
- name: searchText
in: query
description: The Product that needs to be fetched
required: true
schema:
type: string
- name: ctrCode
in: query
description: The Product locale needs to be fetched. Example=en-GB, fr-FR, etc.
required: true
schema:
type: string
- name: pageSize
in: query
description: The Product PageSize that needs to be fetched. Example=10, 20 etc.
required: true
schema:
type: number
- name: pageNo
in: query
description: The Product pageNo that needs to be fetched. Example=1,2 etc.
required: true
schema:
type: number
- name: project
in: query
description: The Project that needs to be fetched. Example=Mypact, DSL etc.
required: true
schema:
type: string

Couchdb Reference Document

I'm new to CouchDB and struggling to implement a basic example. I have three documents Customer, Contact, Address and I want join them into a single document.
Account Document
{
"_id": "CST-1",
"_rev": "8-089da95f148b446bd3b33a3182de709f",
"name": "Customer",
"code": "CST-001",
"contact_Key": "CNT-001",
"address_Key": "ADD-001",
"type": "Customer"
}
Contact Document
{
"_id": "CNT-001",
"_rev": "8-079da95f148b446bd3b33a3182de709g",
"fullname": "Happy Swan",
"type": "Contact"
}
Address Document
{
"_id": "ADD-001",
"_rev": "8-179da95f148b446bd3b33a3182de709c",
"street1": "9 Glass View",
"street2": "Street 2",
"city": "USA",
"type": "Address"
}
Map/Query:
var map= function (doc) {
if (doc.type === 'Customer') {
emit(doc.id, { contact_Key: doc.contact_Key, address_Key: doc.address_Key })
}
};
db.query({ map: map }, { include_docs: true }, function (err, res) {
});
I want all 3 documents in a single document when I query account e.g.
Expected result
{
"_id": "CST-1",
"_rev": "8-089da95f148b446bd3b33a3182de709f",
"name": "Customer",
"code": "CST-001",
"contact_Key": "CNT-001",
"address_Key": "ADD-001",
"type": "Customer",
"Contact: {
"_id": "CNT-001",
"_rev": "8-079da95f148b446bd3b33a3182de709g",
"fullname": "Happy Swan",
"type": "Contact"
}",
"Address: {
"_id": "ADD-001",
"_rev": "8-179da95f148b446bd3b33a3182de709c",
"street1": "9 Glass View",
"street2": "Street 2",
"city": "USA",
"type": "Address"
}"
}
I don't see any better solution than querying the account document first and then querying the other two once you know their IDs. If you think about it, it makes sense because the only link between these documents is the IDs stored in the account document, so to get all three at the same time, internally the DB would have to do two queries: first the account document, then the other two. And by design CouchDB only does one query at a time.
If you had the account doc ID stored into the contact and address documents however, you could use a list function to merge them all into one.
First you would need a view:
function(doc) {
if (doc.type === 'Customer') {
emit(doc._id, doc);
}
if (doc.type === 'Contact' || doc.type === 'Address') {
emit(doc.account_id, doc);
}
}
Then a list function:
function(head, req) {
var row, account, contact, address;
while (row = getRow()) {
if (row.value.type === 'Customer') {
account = row.value;
} else if (row.value.type === 'Contact') {
contact = row.value;
} else if (row.value.type === 'Address') {
address = row.value;
}
}
account['Contact'] = contact;
account['Address'] = address;
provides("json", function() {
return { 'json': account };
});
}
And you would query it with:
GET /db/_design/foo/_list/the-list/the-view?key="CST-1"

Resources