New to Node, and really frustrated with multiple libraries to do the same thing. I am going no where.
I have existing Node + express application, and need to integrate swagger docs.
Most useful thread I found was this one. But it just expects to have parallel api-docs.json file. This is not generated automatically.
I want to document each API in the controller, and want to generate the documents. Can someone point me to better resource?
Finally I was able to make it work with swagger-jsdoc
Steps
Add Swagger-UI package
Add swagger-ui dependency
npm install -g swagger-ui
Configure swagger in your server.js file
var swaggerJSDoc = require('swagger-jsdoc');
var options = {
swaggerDefinition: {
info: {
title: 'Hello World', // Title (required)
version: '1.0.0', // Version (required)
},
},
apis: ['./routes.js'], // Path to the API docs
};
var swaggerSpec = swaggerJSDoc(options);
app.get('/api-docs.json', function(req, res) {
res.setHeader('Content-Type', 'application/json');
res.send(swaggerSpec);
});
app.use('/api/docs',express.static('./node_modules/swagger-ui/dist'));
Add swagger comments to your controller functions
/**
* #swagger
* resourcePath: /api
* description: All about API
*/
/**
* #swagger
* /login:
* post:
* description: Login to the application
* produces:
* - application/json
* parameters:
* - name: username
* description: Username to use for login.
* in: formData
* required: true
* type: string
* - name: password
* description: User's password.
* in: formData
* required: true
* type: string
* responses:
* 200:
* description: login
*/
app.post('/login', function(req, res) {
res.json(req.body);
});
Swagger documentation available at
http://localhost:3000/api/docs/?url=/api-docs.json
Related
So basically I have an Express API that I've been working on and recently I got the idea to implement a documentation for it. I chose Swagger and JSDoc to do this as it is quick and easy. However the documentation won't work. Here is how I've implemented it so far.
docs.ts:
import swaggerJSDoc, { Options } from "swagger-jsdoc";
const swaggerOptions: Options = {
definition: {
info: {
title: "Project Nonya Documentation.",
description: "Documentation for the Project Nonya API",
contact: {
name: "Joe Mama",
},
version: "6.9.0",
},
},
apis: ["./routes/*.routes.ts"],
};
export const swaggerDocs = swaggerJSDoc(swaggerOptions);
router.ts:
...
import swaggerUi from "swagger-ui-express";
import { swaggerDocs } from "./docs";
...
app.use("/api/documentation", swaggerUi.serve, swaggerUi.setup(swaggerDocs));
...
When I got to the docs endpoint, the documentation does appear, however its keeps saying No Operations defined in spec!. Here is one of the files in the routes folder.
testing.routes.ts:
import express, { Router } from "express";
import { testing} from "../controllers/testing/testing.controller";
const router: Router = express.Router();
/**
* #swagger
* /:
* get:
* description: Why you no work?
* responses:
* 200:
* description: Returns nothing cause this shit won't work.
*/
router.post("/testing/:id", testing);
export default router;
What am I doing wrong? I can't figure it out. The directories are like this: src/docs.ts, src/router.ts, and src/routes/testing.router.ts.
Side Question
Since I am using TypeScript, I obviously have to compile the code into JavaScript. However in the apis array in docs.ts, I specify files with a *.routes.ts. Would I have to change this to *routes.js.
Thank You!
Found this Github issue to be the solution to my problem.
https://github.com/Surnet/swagger-jsdoc/issues/150
I am trying to integrate Google Pay web into my website but when i click "pay with googlepay" its shows the below error:
There are no accepted cards available for use with this merchant.
When i read documentation it says you can add example as merchant for testing, I just wanted to use test environment but still its not working.
Here is the code that i am using:
const allowedAuthMethods = ['PAN_ONLY','CRYPTOGRAM_3DS'] ;
const baseCardPaymentMethod = {
type: 'CARD',
parameters: {
allowedCardNetworks: allowedNetworks,
allowedAuthMethods: allowedAuthMethods
}
};
const googlePayBaseConfiguration = {
apiVersion: 2,
apiVersionMinor: 0,
allowedPaymentMethods: [baseCardPaymentMethod]
};
/**
* Holds the Google Pay client used to call the different methods available
* through the API.
* #type {PaymentsClient}
* #private
*/
let googlePayClient;
/**
* Defines and handles the main operations related to the integration of
* Google Pay. This function is executed when the Google Pay library script has
* finished loading.
*/
function onGooglePayLoaded() {
googlePayClient = new google.payments.api.PaymentsClient({
environment: 'TEST'
});
googlePayClient.isReadyToPay(googlePayBaseConfiguration)
.then(function(response) {
if(response.result) {
createAndAddButton();
} else {
alert("Unable to pay using Google Pay");
}
}).catch(function(err) {
console.error("Error determining readiness to use Google Pay: ", err);
});
}
/**
* Handles the creation of the button to pay with Google Pay.
* Once created, this button is appended to the DOM, under the element
* 'buy-now'.
*/
function createAndAddButton() {
const googlePayButton = googlePayClient.createButton({
// currently defaults to black if default or omitted
buttonColor: 'default',
// defaults to long if omitted
buttonType: 'long',
onClick: onGooglePaymentsButtonClicked
});
document.getElementById('buy-now').appendChild(googlePayButton);
}
/**
* Handles the click of the button to pay with Google Pay. Takes
* care of defining the payment data request to be used in order to load
* the payments methods available to the user.
*/
function onGooglePaymentsButtonClicked() {
const tokenizationSpecification = {
type: 'PAYMENT_GATEWAY',
parameters: {
gateway: 'example',
gatewayMerchantId: 'exampleGatewayMerchantId'
}
};
const cardPaymentMethod = {
type: 'CARD',
tokenizationSpecification: tokenizationSpecification,
parameters: {
allowedCardNetworks: ['VISA','MASTERCARD'],
allowedAuthMethods: ['PAN_ONLY','CRYPTOGRAM_3DS'],
billingAddressRequired: true,
billingAddressParameters: {
format: 'FULL',
phoneNumberRequired: true
}
}
};
const transactionInfo = {
totalPriceStatus: 'FINAL',
totalPrice: '123.45',
currencyCode: 'USD',
countryCode: 'US'
};
const merchantInfo = {
merchantId: '01234567890123456789', //Only in PRODUCTION
merchantName: 'Example Merchant Name'
};
const paymentDataRequest = Object.assign({}, googlePayBaseConfiguration, {
allowedPaymentMethods: [cardPaymentMethod],
transactionInfo: transactionInfo,
merchantInfo: merchantInfo
});
googlePayClient
.loadPaymentData(paymentDataRequest)
.then(function(paymentData) {
processPayment(paymentData);
}).catch(function(err) {
// Log error: { statusCode: CANCELED || DEVELOPER_ERROR }
});
}
function processPayment(paymentData) {
// TODO: Send a POST request to your processor with the payload
// https://us-central1-devrel-payments.cloudfunctions.net/google-pay-server
// Sorry, this is out-of-scope for this codelab.
return new Promise(function(resolve, reject) {
// #todo pass payment token to your gateway to process payment
const paymentToken = paymentData.paymentMethodData.tokenizationData.token;
console.log('mock send token ' + paymentToken + ' to payment processor');
setTimeout(function() {
console.log('mock response from processor');
alert('done');
resolve({});
}, 800);
});
} ```
There are no accepted cards available for use with this merchant.
This message means that the current Google user doesn't have any cards that are compatible with the payment options that the merchant has provided. Specifically allowedCardNetworks and allowedAuthMethods.
Here is a JSFiddle that I created based on your snippet: https://jsfiddle.net/aumg6ncb/
This is what I get back after clicking on the button:
If You are using Testing mode:-
I think You used testing card on your Chrome browser or Google Wallet
When testing Google Pay you should have a real card saved in your Chrome browser or Google Wallet, and have your test API keys/test Google Pay environment active. The real card does not get charged, and Google passes a test card during the checkout flow instead of a real card. Our normal test cards do not work with Google Pay when the user tries to save them in Chrome
I am trying to get the ssm parameters in in a js handler as following:
module.exports.post = (event, context, callback) => {
var params = {
Name: 'myParameter',
WithDecryption: true || false
};
ssm.getParameter(params, function(err, data) {
if (err) console.log(err, err.stack);
else console.log(data);
});
};
and I added the following permission roles to my serverless.yml file
iamRoleStatements:
- Effect: Allow
Action:
- ssm:GetParameters
- ssm:GetParameter
- ssm:DescribeParameters
- kms:Encrypt
- kms:Decrypt
Resource: "*"
Using the CLI I can successfully perform aws ssm get-parameter --names myParameter
but when I invoke the function I get the following error in cloudWatch
AccessDeniedException: User: myUser is not authorized to perform:
ssm:GetParameter on resource: myResource/myParameter
I have tried to use getParameters functions, get the exact name resource but still the same error message.
Any help would be much appreciated.
Just created a project with serverless and it worked as expected.
The permissions are set in serverless.yml with only the grants required for execution of the code.
serverless.yml
service: poc-lambda-ssm
provider:
name: aws
runtime: nodejs8.10
variableSyntax: "\\${((?!AWS)[ ~:a-zA-Z0-9._'\",\\-\\/\\(\\)]+?)}"
iamRoleStatements:
- Effect: Allow
Action:
- ssm:GetParameter
Resource:
- 'Fn::Join':
- ':'
- - 'arn:aws:ssm'
- Ref: 'AWS::Region'
- Ref: 'AWS::AccountId'
- 'parameter/my-secure-param'
- Effect: Allow
Action:
- kms:Decrypt
Resource:
- 'Fn::Join':
- ':'
- - 'arn:aws:kms'
- Ref: 'AWS::Region'
- Ref: 'AWS::AccountId'
- 'key/alias/aws/ssm'
functions:
hello_ssm:
handler: handler.hello_ssm
handler.js
'use strict';
const AWS = require("aws-sdk")
AWS.config = {
region:"us-east-1"
};
const ssm = new AWS.SSM({apiVersion: '2014-11-06'});
module.exports.hello_ssm = function(event, context, callback) {
var params = {
Name: 'my-secure-param',
WithDecryption: true
};
ssm.getParameter(params, function(err, data) {
if (err) callback(err);
else callback(null,"my secure param is: "+data.Parameter.Value);
});
};
and created a parameter called my-secure-param in AWS System Manager with type SecureString.
You also might check my PoC Lambda SSM project. In this project I use serverless to develop lambda and it works invoking locally by using invoke local -f hello_ssm.
I have an angular2 app where I need to use a payment API.
https://stripe.com/docs/quickstart
In this code sample on the nodejs section they say to use it like this:
// Set your secret key: remember to change this to your live secret key in production
// See your keys here: https://dashboard.stripe.com/account/apikeys
var stripe = require("stripe")("sk_test_BQokikJOvBiI2HlWgH4olfQ2");
// Token is created using Stripe.js or Checkout!
// Get the payment token submitted by the form:
var token = request.body.stripeToken; // Using Express
// Charge the user's card:
var charge = stripe.charges.create({
amount: 1000,
currency: "usd",
description: "Example charge",
source: token,
}, function(err, charge) {
// asynchronously called
});
We installed requireJS with NPM, however when we run it we get this error:
Cannot find name 'require'.
L48: pagar() {
L49: var stripe = require("stripe")("sk_test_ayzCMDmjq2QOIW0s3dTihxNR");
Try this instead:
import * as stripe from "stripe";
public stripeKey = stripe("sk_test_BQokikJOvBiI2HlWgH4olfQ2");
i have an error wir my Js Routing configuration.
I get "Uncaught Error: The route "pspiess_letsplay_customer_new" does not exist." in my console log.
I have installed the bundle via composer.
i have done all the 4. Steps
My Symfony version 2.3.21
My AppKernel
$bundles = array(
//.....
new pspiess\LetsplayBundle\pspiessLetsplayBundle(),
new Knp\Bundle\MenuBundle\KnpMenuBundle(),
new Braincrafted\Bundle\BootstrapBundle\BraincraftedBootstrapBundle(),
new JMS\SerializerBundle\JMSSerializerBundle(),
new FOS\JsRoutingBundle\FOSJsRoutingBundle(),
//.....
);
My routing.yml
fos_js_routing:
resource: "#FOSJsRoutingBundle/Resources/config/routing/routing.xml"
pspiess_letsplay:
resource: "#pspiessLetsplayBundle/Controller/"
resource: "#pspiessLetsplayBundle/Resources/config/routing.yml"
prefix: /
My route
pspiess_letsplay_customer_new:
pattern: /admin/customer/new
defaults: { _controller: pspiessLetsplayBundle:Customer:new }
My Action
/**
* Displays a form to create a new Customer entity.
*
* #Route("/new", name="customer_new")
* #Method("GET")
* #Template()
*/
public function newAction() {
$entity = new Customer();
$form = $this->createCreateForm($entity);
return array(
'entity' => $entity,
'form' => $form->createView(),
);
}
My Js Code
click: function() {
console.log(Routing.generate('pspiess_letsplay_customer_new'));
}
My "router:debug" - all routes found with my route
pspiess_letsplay_booking_new ANY ANY ANY /admin/booking/new
My "fos:js-routing:debug" - no route found
I think there is something wrong wirth my routing configuration, but i dont know what.
Thanks for help.
Arent you missing the expose option in your routing ?
pspiess_letsplay_customer_new:
pattern: /admin/customer/new
defaults: { _controller: pspiessLetsplayBundle:Customer:new }
options:
expose: true