I'm trying to use https://www.npmjs.com/package/json-server as a mock backend, I'm able to match URLs for get, but how can i return some mock-response for POST calls.
Like for create user URL will be like
URL - http://localhost:4000/user
Method - POST
Request Data - {name:"abc", "address":"sample address"}
expected response -
httpStats Code - 200,
Response Data - {"message":"user-created", "user-id":"sample-user-id"}
In Some Cases I also want to send custom http codes like 500,423,404,401 etc.. depending upon some data.
Biggest problem is that my code is not returning anything response for POST, its only inserting records in JSON
By default POST requests through json-server should give a 201 created response.
If you need custom response handling, you might need a middleware to get hold of req and res object.
Here I'm adding a middleware to intercept POST requests and send a custom response. You could tweak it to your specific case.
// Custom middleware to access POST methods.
// Can be customized for other HTTP method as well.
server.use((req, res, next) => {
console.log("POST request listener");
const body = req.body;
console.log(body);
if (req.method === "POST") {
// If the method is a POST echo back the name from request body
res.json({ message:"User created successfully", name: req.body.name});
}else{
//Not a post request. Let db.json handle it
next();
}
});
Complete code (index.js)..
const jsonServer = require("json-server");
const server = jsonServer.create();
const router = jsonServer.router("db.json");
const middlewares = jsonServer.defaults();
server.use(jsonServer.bodyParser);
server.use(middlewares);
// Custom middleware to access POST methids.
// Can be customized for other HTTP method as well.
server.use((req, res, next) => {
console.log("POST request listener");
const body = req.body;
console.log(body);
if (req.method === "POST") {
// If the method is a POST echo back the name from request body
res.json({ message:"User created successfully", name: req.body.name});
}else{
//Not a post request. Let db.json handle it
next();
}
});
server.use(router);
server.listen(3000, () => {
console.log("JSON Server is running");
});
And you can start json-server using node index.js
Related
I have an api which communicates with a third party service. This third party service uses two live server url's which it uses to asynchronously pass the actual response with of any kind of communication with the service - result and error back to my application using webhook. So I created a tunnel with ngrok and I also created two urls (http request listener i.e route) which receive the result/error from the service. Hence when I hit api 1, the actual response is passed in req.body to the listener 1 & 2. What now I need to figure out is if there is any way to pass this response from the webhook listener back to api 1, or if there is any way the async flow of my api 1 can keep going on by communicating directly with the webhook listener.
//Controller
const sendPaymentRequest = async (req, res) => {
try {
//Send payment request to 3rd party service
const endpoint = "/mpesa/b2c/v1/paymentrequest";
const url = MPESA_URL + endpoint;
const config = {
headers: {
Authorization: `Bearer ${access_token}`,
},
};
const body = {
Remarks: "Sending money from mobile wallet",
QueueTimeOutURL: "http://f815c811f619.ngrok.io/api/v1/b2c/error",
ResultURL: "http://f815c811f619.ngrok.io/api/v1/b2c/result",
};
const payment_reponse = await axios.post(url, body, config);
const { data } = payment_reponse;
console.log("Payment request => ", data); //Not the actual response
//*------------Need actual response from the listener in routes.js--------//
res.status(200).json({ message: "Send money request", data });
} catch (error) {
console.log("Error while making a payment request", error);
res
.status(400)
.json({ message: "Error while send payment request", error: error.data });
}
};
//Routes.js
this.router.post("/b2c/result", (req, res) => {
console.log(req.body); //Actual response from API-1
});
this.router.post("/b2c/error", (req, res) => {
console.log(req.body); //Error if any from API-1
});
I don't think you can wait for the webhook call inside the api 1 block.
You could persist this request in a database, and when the payment API calls your webhook can query your database for information about the original request and process the information based on that.
I have question about route to get both request from param and body
My route is to delete user. It looks like this:
router.delete("/delete/:id",middleware, async (req, res) => {
//firstly, I get param:
var userId = req.params.id || '';
//if emty, it will get request from body
if(!userId){
const listId = req.userIds
}
});
I perform request but it shows error: Cannot DELETE /api/users/delete
http://localhost:5000/api/users/delete/
Can you explain me what wrong with my issue?
Based on your latest comment you will need a route for collection delete as well as the model route. Here is some "pseudocode":
// model form
router.delete("/delete/:id",middleware, async (req, res) => {
var userId = req.params.id
// made up backend service - add error handling, etc
await dataService.users.delete(userId);
res.sendStatus(200); // again with error stuff
});
// collection form
router.delete("/delete",middleware, async (req, res) => {
var userIds = req.body.userIds; // assumes use of bodyParser
for (userId in userIds) {
// made up backend service - add error handling, etc
await dataService.users.delete(userId);
res.sendStatus(200); // again with error stuff
}
});
I am trying to fetch data from Mongodb and i want that data to show up on my web page.The problem is i don't know how to send the whole fetched object to a specific port (the response) so that i'll be able to fetch it from Angular and how will i be able to access data from Angular
Fetching data from Mongodb
app.get('/api/getdata',async (req,res) =>
{
const {value} = req.body
const resp=await person.find({value})
if(!resp){
console.log('not found')
}
else{
//this needs to be done
}
})
Please, have a look at express API reference
then your code would look like :
app.get('/api/getdata', async (req,res) => {
const {value} = req.body
const resp = await person.find({value})
if (!resp) {
res.status(404).send('not found')
}else{
// give your data to express response to the http request
res.json(resp); // or res.send(resp);
}
});
In my Express app I am receiving a payload from an external POST request:
router.post('/liveReleaseStore', (req,res) => {
let thing = req.body.myPayload
...
I also handle a GET request from my client:
router.get('/liveReleaseStore', (req, res) => {
let myResponse = ...
res.send(myResponse);
});
I need to reroute the payload so that when my client sends a GET to the server I am able to send back the data or tell the client that I haven't received any data yet.
What is the best way to about about this?
Thanks
You could initialize the data outside the two functions to null. And then send the data if it's been initialized by the post function.
let thing = null;
router.post('/liveReleaseStore', (req,res) => {
let thing = req.body.myPayload
...
}
router.get('/liveReleaseStore', (req,res) => {
if (thing === null)
return res.send('no data yet');
res.send(thing);
}
I'm running into a small issue with something I thought was possible.
I want to have two express routes, one GET route /post-data and one POST route /post-recieve.
The code would look something like this:
app.get('/post-data', (req, res, next) => {
//set url to '/post-recieve' and set body / headers
})
app.post('/post-recieve', (req, res, next) => {
return res.json(res.body)
})
Now, when you visit /post-data you should be instantly redirected to /post-recieve except if you look in the developer console you should see that the method for the document is POST and not a normal GET request.
Is this possible?
I know you can use a library like request to make a HTTP post request to an endpoint, but I'm talking about actually sending the user to the page via a POST request.
This feels so dumb, but it might be the only way???
function postProxyMiddleware (url, data) {
return (req, res, next) => {
let str = []
str.push(`<form id="theForm" action="${url}" method="POST">`)
each(data, (value, key) => {
str.push(`<input type="text" name="${key}" value="${value}">`)
})
str.push(`</form>`)
str.push(`<script>`)
str.push(`document.getElementById("theForm").submit()`)
str.push(`</script>`)
return res.send(str.join(''))
}
}
app.get('/mock', postProxyMiddleware('/page', exampleHeaders))
The only way to change the client's request method from GET to POST programmatically is to create a form containing hidden elements with method="post" and action="/post-receive", then using client-side JavaScript to automatically submit the form.
Any HTTP redirects in response to a GET request will also be GET.
You can use request-promise to post the data to a url. So, initiate with this function and you can get the data in the api url
const request = require('request');
const rp = require('request-promise');
let req = {
"param1" : "data1",
"param1" : "data2"
}
rp({
method: 'POST',
uri: 'http://localhost:3000/post-data/',
body: req,
json: true // Automatically stringifies the body to JSON
}).then(function (parsedBody) {
console.dir(parsedBody);
return parsedBody;
// POST succeeded...
})
.catch(function (err) {
console.log(err+'failed to post data.');
return err+'failed to post data.';
// POST failed...
});
Apologies If I get your question wrong.