Im a beginner at swagger. What im trying to do is creating an API and the problem is when test it on Postman, the Postman can't find the API.
This is my router:
router
/**
* #swagger
* /orders/{id}/status:
* put:
* summary: accept the order
* tags: [Order]
* description: this action can accessd by driver or admin
* responses:
* 200:
* description: The order was updated
*
* 404:
* description: you are not authorized to access this route
* 500:
* description: Some error happened
*/
.route("/:id/status")
.put(protect, authorize("user", "admin"), requestOrder);
This is my controller:
//#route put/api/v1/orders/:id
//#access private for admin & user who create the order
exports.requestOrder = asyncHandler(async (req, res, next) => {
const updatedOrder = await Order.findByIdAndUpdate(
{ _id: req.params.id },
{ status: req.body.status },
{
new: true,
}
);
if (!updatedOrder) {
return next(
new ErrorResponse(`error ${req.params.id}`, 404)
);
}
res.status(200).json({
success: true,
msg: ` order with id ${req.params.id} is updated`,
data: updatedOrder,
});
});
I'm wondering if it is any mistake in the swagger code since i'm a beginner, and not sure if I can notice any mistake in it.
In the postman I get error 404 (Cannot PUT)
Also im using MongoDb as a database.
Did you create a Swagger config file and added your servers?
Example:
//./configs/openapi.js
module.exports = {
openapi: '3.0.0',
info: {
title: 'Your API Titel',
description: '',
termsOfService: '',
contact: {
name: 'Your contact Details',
url: 'https://example.com',
},
license: {},
},
servers: [
{
url: 'http://localhost:2000/api',
description: 'Local development server',
}
]
};
And then you need to import the config file in app.js
const express = require('express')
const app = express()
const swaggerJSDoc = require('swagger-jsdoc');
swaggerDefinition = require('./config/openapi.js')
const options = {
swaggerDefinition,
// Paths to files containing OpenAPI definitions
apis: ['src/routes/*js']
};
const swaggerSpec = swaggerJSDoc(options);
api.listen(config.api.port, () => {
console.log('Server running at port 2000')
})
Related
Below is my Next.js (backend API) code to verify recaptcha token (created from the client side) and send a mail.
import { NextApiRequest, NextApiResponse } from "next";
import NextCors from 'nextjs-cors';
import { recaptchaAxios } from "../../axios/axiosBackend";
import sendGridMail from '#sendgrid/mail';
sendGridMail.setApiKey(process.env.SENDGRID_API_KEY);
interface FormData {
contactName: string;
contactEmail: string;
contactPhone: string;
contactSubject: string;
contactMessage: string;
token: string;
}
export default async (req: NextApiRequest, res: NextApiResponse) => {
await NextCors(req, res, {
// Options
methods: ['GET','POST'],
origin: '*',
optionsSuccessStatus: 200, // some legacy browsers (IE11, various SmartTVs) choke on 204
});
const formData: FormData = req.body;
console.log("form Data >>>>>>>>>>>>>>",formData)
const human = await validateHuman(formData.token);
if (!human) {
res.status(400);
return res.json({ success: false, errors: ["You are not authenticated"] });
}
const message = {
to: process.env.SENDGRID_MAIL_RECEIVER,
from: process.env.SENDGRID_MAIL_SENDER, // Change to your verified sender
subject: formData.contactSubject,
text: `Name: ${formData.contactName}\n
Contact: ${formData.contactPhone} \n
Email: ${formData.contactEmail} \n
Message: ${formData.contactMessage}`,
html: `Name: ${formData.contactName}
Contact: ${formData.contactPhone}
Email: ${formData.contactEmail}
Message: ${formData.contactMessage}`,
}
try {
await sendGridMail.send(message);
res.status(200);
return res.json({ success: true, errors: [] });
} catch (error) {
console.log(error);
res.status(500);
return res.json({ success: false, errors: ['Error occured while trying to send your details. Please contact your Administrator.']});
}
};
async function validateHuman(token: string): Promise<boolean> {
const secret = process.env.RECAPTCHA_SECRET_KEY;
const response = await recaptchaAxios.post(`/siteverify?secret=${secret}&response=${token}`,{}, {});
const success = response.data['success'];
console.log("server siteverify >>>>>>>>>>>>>",response);
return success;
}
recaptchaAxios has the baseURL as below
const recaptchaAxios = axios.create({
baseURL: `https://www.google.com/recaptcha/api`,
});
I have deployed the same code in vercel as well as using AWS Amplify.
In vercel when called to the above mail API, the Recaptcha token is verified and the mail is sent.
But unfortunately in AWS it gives the error
{ success: false, errors: ["You are not authenticated"] }
I have added all the environment variables in AWS which I have in vercel and the values are the same.
All the domains are added in reCaptch v3 console for the site.
So at this point I am stuck on why in AWS gives the error, but not vercel for the same code base
Is there anything that I am missing in AWS??
Cheers
My first pointer would be to console.log the environment variables on script load, also each time the recaptcha validation is triggered. This way you can be sure the ENV vars are all loaded correctly. You would be suprised to have a small case sensitivity typo, leave you without an important env variable.
Otherwise, I would check if I need to allow outgoing traffic (firewall rules) on AWS amplify, but this is less common, since AWS Amplify spawns a public site.
Issue was in the below code
const secret = process.env.RECAPTCHA_SECRET_KEY;
Even though the RECAPTCHA_SECRET_KEY was available in the environment variables in AWS, it was not accessible.
Fix was to introduce this key in next.config.js file
module.exports = {
images: {
domains: [],
},
env: {
RECAPTCHA_SECRET_KEY: process.env.RECAPTCHA_SECRET_KEY,
},
};
This solved the problem
I have the following controller w/ sign-up functionality:
// ".../controller.js"
import mongoose from 'mongoose';
const route = Router();
export default (app: Router) => {
app.use('/auth', route);
/**
* API-Route for user signup & registration process
* #param phone phone number of user
* #param password password of user
* #param dob dob of user
* #param name name of user
* #param gender gender of user
* #return uid of user and message
* */
route.post(
'/signup',
middlewares.multer.single('photo'), // multer middleware for getting profile photo
celebrate({
body: Joi.object().keys({
phone:
password:
name:
gender:
dob:
}),
}),
async (req: Request, res: Response, next: NextFunction) => {
/* "Sign-up Service is Called Here to Store in Database" */
}
Then, I make a test folder and want to write a test that will call this controller and pass it the phone,password etc values so that i can see if its storing it in the DB.
NOTE: that i want to send the data from within the code.
"As shown above, the controller is being developed in JavaScript and the database I am using is MongoDB."
I tried to do the same thing that was done here...
https://www.theodinproject.com/paths/full-stack-javascript/courses/nodejs/lessons/testing-routes-and-controllers
...however, its different from what I am trying to do
var adduser = new User({
phone: req.body.phone,
password: req.body.password,
name: req.body.name,
gender: req.body.gender,
dob: req.body.dob,
});
adduser
.save()
.then((data) => {
return res.status(200).send({
status: 200,
success: true,
data: data,
message: "user is inserted",
});
})
.catch((err) => {
return res.status(400).send({
status: 400,
success: false,
err: err,
});
});
You can store the data with this pattern in the mongoose. but the User after the new keyword is model which we have to create & then import in this file. if you data is stored correctly with out any error then is send response 200 & show the data you can check in postman
I am making an API using Node.js that connects to an SQL Server database. My GET requests work well, but my POST request gives me errors. I have divided my node project into two files, a routes file and a controllers file.
The code in my routes file is as follows:
module.exports = (app) => {
const UsrContrllr = require('../Controllers/users.controllers');
//1. GET ALL USERS
app.get('/api/users', UsrContrllr.getAllUsers);
//2. POST NEW USER
app.post('/api/user/new', UsrContrllr.addNewUser);
};
And the code in my controllers file is given below:
const mssql = require('mssql');
exports.getAllUsers = (req, res) =>
{
// Validate request
console.log(`Fetching RESPONSE`);
// create Request object
var request = new mssql.Request();
// query to the database and get the records
const queryStr = `SELECT * FROM USERS`;
request.query(queryStr, function (err, recordset) {
if (err) console.log(err)
else {
if (recordset.recordset.toString() === '') {
res.send('Oops!!! Required data not found...');
}
else {
// send records as a response
res.send(recordset);
}
};
});
};
exports.addNewUser = (req, res) =>
{
// Validate request
console.log(`INSERTING RECORD ${req.body}`);
// create Request object
var request = new mssql.Request();
// query to the database and get the records
const queryStr = `INSERT INTO USERS (USERCODE, PASSWORD, LANGUAGE, USERCLASS, FIRSTNAME, LASTNAME, CONTACTNO) VALUES ('${req.body.usercode}', '${req.body.password}', 'EN', '0', '${req.body.firstname}', '${req.body.lastname}', '${req.body.contactno}');`;
console.log(queryStr);
request.query(queryStr, function (err, recordset) {
if (err) console.log(err)
else {
if (recordset.recordset.toString() == '') {
res.send('Oops!!! Required data not found...');
}
else {
// Send records as response
res.send(recordset);
}
};
});
};
When I run the POST request from my angular application, I get an HttpErrorResponse, Error 404 not found.
error: “Error: Cannot POST /api/users/new"
message: "Http failure response for http://url:port/api/users/new: 404 Not Found"
name: "HttpErrorResponse"
ok: false
status: 404
statusText: "Not Found”
url: "http://url:port/api/users/new”
The angular code in the service file is as follows:
private url = 'http://url:port/api/users';
signup(fName: string, lName: string, usrCode: string, pwd: string, cntctNbr: string) {
const headers = new HttpHeaders().set('Content-Type', 'application/json');
const newUsr = {
usercode: usrCode,
password: pwd,
firstname: fName,
lastname: lName,
contactno: cntctNbr
}
this.http.post(this.url + '/new', JSON.stringify(newUsr), { headers: headers }).subscribe(data => {
console.log(data);
});
}
I don’t understand why I am unable to add in new users. I’ve been told my code appears fine, but I don’t see any results. Where am I going wrong?
You are receiving a 404 (Not found) error because your POST route is defined as /user/new but in your angular app you are calling http://url:port/api/users/new
Correct the code to the following in your API:
app.post('/api/users/new', UsrContrllr.addNewUser);
I need help troubleshooting I CORS error I am having in Apollo, Node, and Next.js. I am not sure what change I have made, but suddenly I am unable to fetch the data from my Prisma database. I am currently running dev mode. My Yoga server which pulls in my data from Prisma run at localhost:4444. My frontend is run on localhost:7777.
Here is my CORS setup:
import withApollo from "next-with-apollo";
import ApolloClient from "apollo-boost";
import { endpoint, prodEndpoint } from "../config";
import { LOCAL_STATE_QUERY } from "../components/Cart";
function createClient({ headers }) {
return new ApolloClient({
uri: process.env.NODE_ENV === "development" ? endpoint : prodEndpoint,
request: (operation) => {
operation.setContext({
fetchOptions: {
credentials: "include",
},
headers,
});
},
// local data
clientState: {
resolvers: {
Mutation: {
toggleCart(_, variables, { cache }) {
// read the cartOpen value from the cache
const { cartOpen } = cache.readQuery({
query: LOCAL_STATE_QUERY,
});
// Write the cart State to the opposite
const data = {
data: { cartOpen: !cartOpen },
};
cache.writeData(data);
return data;
},
},
},
defaults: {
cartOpen: false,
},
},
});
}
export default withApollo(createClient);
variables.env
FRONTEND_URL="localhost:7777"
PRISMA_ENDPOINT="https://us1.prisma.sh/tim-smith-131869/vouch4vet_dev_backend/dev"
PRISMA_SECRET="..."
APP_SECRET="..."
STRIPE_SECRET="..."
PORT=4444
backend index.js
const server = createServer();
server.express.use(cookieParser());
// decode the JWT so we can get the user Id on each request
server.express.use((req, res, next) => {
const { token } = req.cookies;
if (token) {
const { userId } = jwt.verify(token, process.env.APP_SECRET);
// put the userId onto the req for future requests to access
req.userId = userId;
}
next();
});
I have tried rolling back to previous commit and I have had no luck. I have not ruled out internet problems.
Let me know if you need to see the rest of my repo.
Thanks
I have written the code shown below to send the push notification:
const pushpad = require('pushpad');
require('dotenv').config();
const axios = require('axios');
const project = new pushpad.Pushpad({
authToken: process.env.PUSH_PAD_AUTH_TOKEN,
projectId: process.env.PUSH_PAD_PROJECT_ID
});
console.log('called pushpad');
let notification = new pushpad.Notification({
project: project,
body: 'Hello world!',
title: 'Website Name',
targetUrl: 'http://example.com',
iconUrl: 'http://example.com/assets/icon.png',
imageUrl: 'http://example.com/assets/image.png',
ttl: 604800,
requireInteraction: true,
customData: '123',
actions: [
{
title: 'My Button 1',
targetUrl: 'http://example.com/button-link',
icon: 'http://example.com/assets/button-icon.png',
action: 'myActionName'
}
],
starred: true,
sendAt: new Date(Date.UTC(2016, 7 - 1, 25, 10, 9)),
customMetrics: ['examples', 'another_metric']
});
// deliver to everyone
notification.broadcast(function (err, result) {
console.log("error is " + err);
});
module.exports = notification;
but somehow, as soon as I run this code, it gives me error Unprocessable Entity . So how to solve this error ?
Probably you have entered some wrong parameters. For example customMetrics must be defined in your project settings before using them.
Try the same code with a simple notification:
let notification = new pushpad.Notification({
project: project,
body: 'Hello world!'
});