sending key/value data via POST method in a REST API - javascript

I'm working on a REST API that includes a POST method to create new widgets.
The data that I need to send looks like this:
key | value
widgetnum | 12345
02:00:00_03:00:00_mtwrfsn | johndoe#myemail.com
12:00:00_15:00:00_mt | janedoe#yahoo.com
Up until now, I have been POSTing data via two keys in the BODY:
widgetnum : 12345
tc : 02:00:00_03:00:00_mtwrfsn_johndoe#myemail.com,12:00:00_15:00:00_mt_janedoe#yahoo.com
As you can see in the example above, the key "tc" actually contains information for two records, just separated by a comma.
But yesterday as i was poking around in the Postman application... I realized that I can send multiple key / value pairs. I don't know why this never clicked before. (such a noob) In any case, I realize now, I can actually do this:
widgetnum : 12345
02:00:00_03:00:00_mtwrfsn : johndoe#myemail.com
12:00:00_15:00:00_mt : janedoe#yahoo.com
Questions
Is it more efficient to change way I POST data as far as my javascript code is concerned? So for example, today, my code looks like this:
router.post('/', function(req, res, next) {
var widgetnum = req.body.widgetnum;
var tc = req.body.tc;
var tc_array = tc.split(",");
aka - I'm able to look for my data using very specific key names.
However, if I change the way I POST my data, I believe I would have to loop to find all the keys.
So something like this:
router.post('/', function(req, res, next) {
//loop through req.body object.
for (var key in req.body) {
if (req.body.hasOwnProperty(key)) {
// add some logic here to test if the key is
// widgetnum or a tc type key.
console.log(key + " -> " + req.body[key]);
}
}
res.status(200).send('ok');
return;
});
I apologize if this seems like a remedial question - it probably is.
But if it's bad form to POST multiple tc records in one key/value pair, I'm happy to change it. Perhaps there's a more efficient way to write my javascript code to find the data.
Thanks.

To send and receive key/value pair, format already exist that (almost) does the work for you. One of them is JSON, which is widely supported, especially in JavaScript.
Since you are using express already, you can add body-parser and set it to automatically parse JSON:
Data sent (POSTMan: body type: application/json, copy paste in the body.
{
"widgetnum" : 12345,
"tc" : {
"02:00:00_03:00:00_mtwrfsn": johndoe#myemail.com,
"12:00:00_15:00:00_mt": janedoe#yahoo.com
}
}
Server code:
"use strict";
const express = require('express'),
router = express.Router(),
bodyParser = require('body-parser');
router.use(bodyParser.json());
router.post('/', function(req, res, next) {
var widgetnum = req.body.widgetnum;
var tc = req.body.tc;
//No more need for tc_array
//...
}
No more need for your custom format, and req.body will be a JS object of the same form as the JSON sent, so you can do things like:
console.log(req.body.tc['02:00:00_03:00:00_mtwrfsn']); //print johndoe#myemail.com
console.log(Object.keys(req.body.tc)); //Print ['02:00:00_03:00:00_mtwrfsn', '12:00:00_15:00:00_mt']

Related

How to create an express update route with multiple parameters

I want to update an attribute within a JSON object using fetch PUT. I've created a put function taking in 2 URL parameters
app.put('/trustRoutes/:id/:item', (req, res){
I am able to update the data with a single parameter but since I only want to change one value inside that object, calling put will replace the whole object with my new body.
below is what I've tried.
app.put('/trustRoutes/:id/:item', (req, res) => {
readFile(data => {
const userId = req.params['id/item'];
// have also tried const userId = req.params.id.item
data[userId] = req.body;
//write data back to file
I looked around at other examples but couldn't find any that were updating data instead of GET. If there is one I missed please let me know.
PUT requests are great for completely overwriting a resource, and is idempotent. This answer does a good job explaining idempotency. For updating a resource partially, a PATCH request is a better choice.
app.patch('/trustRoutes/:id/:item', (req, res) => {
readFile(data => {
data[userId] = req.params[id];
data[item] = req.params[item];
// A get request for this resource would now show both of the updated values
// Write file

Send body JSON with Postman in a POST method to execute procedure in ms sql server

I want to send a JSON (body) on Postman with POST method and receive a result.
Im a trainee and my boss asked me this. I've been looking in web for a week and didn't find. I said to him that method to receive a data is GET, but he said that GET has a limit on URL. If the stored procedure have a lot of parameters we will not receive the expected result, so a I have to use Post method.
This is my code to connect to ms sql server:
var express = require('express');
var app = express();
var sql = require('mssql');
var config = {
user: 'MY_USER',
password: 'MY_PASS',
server: 'MY_SERVER',
database: 'MY_DB'
};
Searching in google I found a way to execute a procedure with GET method. In the browser I put the value I want and I receive the result, but is not still what he wants. The code is:
app.get('/get/:pNU_EST001', function (req, res) {
//conexão com o DB
sql.connect(config, function(){
var request = new sql.Request();
request.input('pNU_EST001', req.params.pNU_EST001);
request.execute('dbo.ESTSP004_ConsultaLivrosEmprestadosAluno_XX', function(err, recordsets, returnValue, affected) {
if(err) console.log(err);
res.send(recordsets);
//res.end(JSON.stringify(recordsets)); /*--- result in JSON format ---*/
});
});
});
On Postman he showed me a example with DB2, but I couldn't see the code. On Post Method, on HEADERS it has two key:
KEY => Content-Type (value: application/json) // KEY => Accept (value: application/json)
And in his example, on BODY, he wrote a JSON like: { "pNU_EST001" : "3"} and received the related result below. That's what I need.
Express has a few other verbs to use you are using
app.get but there is also app.post if you change your code to use the latter instead it will handle a post request
app.post('/path', function (req, res) {
Then in express to get values from the POST body you get that from
req.body property
So in your case you would want to use req.body.pNU_EST001 instead of req.params.pNU_EST001

ExpressJS + JWT. What's the proper way to get auth data?

Let's jump to an example. I'll skip some parts like imports, exports.
I have a controller called controllers/book.js with one route:
router.get('/my-books', function(req, res) {
if(Auth.authenticated(req,res)) {
Book.getMyBooks(function(rows) {
response.operationSucceed(req, res, rows);
});
}
});
Then, in a model called models/book.js I have that function:
function getMyBooks(successCallback) {
db.query('SELECT * FROM book b WHERE b.id_user=?', [Auth.getLoggedUID()], function(rows) {
successCallback(rows);
});
}
My question is about Auth.getLoggedUID function.
Assuming that I have a JWT authentication and assuming that I have an UID in payload (is that even acceptable?), what's the best option to retrieve it? Is there any, EXCEPT passing the req every time to every function where I need auth data?
I may have a function execution inside a function, do I need to pass the req through both of them to get the user ID? Like this?:
function getBooks(req) {
getMyBooks(req);
getCriminalBooks(req);
getEvenOtherBooksByAuthor(req, authorId);
}
Honestly I wouldn't like that.
Maybe my whole concept is wrong and I should be doing things differently?
Can someone point me the right direction in scenarios like this?
You can pass UID in header and retrieve it inside your controller as:
var uid =req.header('UID');
Then pass this UID where ever you want there is no need to carryforward whole req object everywhere.
You can use a middleware function. Let's say that every request that hits your endpoints, will have a token which you should check and possibly decode it. After that, you can set the decoded content to the req object. So something like this:
app.use(function(req, res, next) {
// get the token from the request headers most likely.
// verify and decode the token
// set the decoded content to the request
var payload = ..
req.payload = payload;
});
After this you can access the payload in every single endpoint you have. So for example in some controller you can do:
app.get('/hey', function(req, res) {
var payload = req.payload;
});

Neither Node.js PUT or POST routes are presenting the data that is being received

I tried this with a number of different modules and methods.
Even by proving the other modules do work as expected in Node by building a separate test project and testing each module individually.
Posting FROM Node's hosted router to a remote API (not TO Node's hosted API)
This problem is not one of SENDING data to an API. It must IMO a problem in the receiving API's not giving up the data it IS receiving for some reason.
I've proven the PUT or POST calls are sending the data by sending the call to http://httpbin/org. That site shows me I'm sending what I expect to be sending.
Here is how I'm sending. I can even see in the receiving API that that API is certainly getting called successfully.
-- sending -- ((Again. This shows my node.http attempt. But I get the same problem using requestjs, requestifyjs, needlejs))
router.get('/', function (req, res, next) {
var hst = req.headers.host.split(':');
var lookbackURL = 'https://' + req.headers.host + req.baseUrl;
lookbackURL = 'http"httpbin.org/put';
var dat = {
what: 'ever'
, try: 'again'
};
var bdy = JSON.stringify(dat);
var options = {
host: hst[0], port: hst[1], path: req.baseUrl, method: 'PUT'
, headers: { 'Content-Type': 'application/json' }
};
var r = nodeHttp.request(options); r.write(bdy); r.end();
res.sendStatus(200);
});
-- receiving --
router.put('/', function (req, res, next) {
console.log('r', req);
});
No matter what module or method I use, in all cases, the receiving req object doesn't contain the what or try data.
BUT in my test project the data is there as I expect it to be, in all cases.
Doing the same console.log(req); in the test project, reqestjs, requestjs, needlejs, node.http all show a proper body object.
But in this problem there isn't a body object in req.
And sending this put/post to http://httpbin.org I can see the body object is being sent.
Any ideas?
Issue found. And it was something no one on here could have gotten for the code I posted.
For reasons I will not go into I have to take body-parser out this application. This also means app.use() won't have a parser given to it.
And that means I have to deal with getting the data on my own. So I've added a req.on('data') listener to read the chunk from the call to the API.
router.put('/', function (req, res, next) {
var data = '';
req.on('data', function (chunk) {
data += chunk;
.....
});
.....
I also decided to do this as a PUT using Requestify.
This just goes to show how easy it is to become complacent and forget how things really work; the assumption of body-parser (or other things) always being there for instance. Or what it is really doing for you.
NEXT I have to figure out how to get a value out of the `req.on('data) back to the method PUTting to the API. Any tips? Appreciated.

Storing JSON POST data in an array (NodeJS)

I would like to be able to post user-generated JSON objects to a NodeJS server, and store them in an array so that refreshing the page does not affect the data. I would then like to be able to read the info back into a table, so that it constantly reflects the contents of the array.
Is this possible in NodeJS? If so, could someone please give me a pointer in the right direction? I'm able to pass JSON objects (as req.body), but I don't know where to go from here.
Thanks!
As Sri suggested, you should definitively store your data array into a data base.
Use either Redis, Mongo, MySQL... It entierly depends on your data shape and the ways you will use it.
If you just neet to store temporary an array (by temporary, I mean "as long as the browsing session" or "as long as the server is up"), you can just store you data in memory.
For exemple with ExpressJs:
var express = require('express');
// in memory storage
var data = [];
var app = express()
.use(express.bodyParser())
.use(express.cookieParser())
.use(express.cookieSession({secret:'sample'}))
.post('/data', function(req, res){
// do not need session, just memmory ? use this line
// data.push(req.body);
// creates the session if needed, and store data
if (!req.session.data) {
req.session.data = [];
}
req.session.data.push(req.body);
res.send(204);
})
.get('/data', function(req, res){
res.setHeader('Content-Type', 'application/json');
// stored in session ?
res.send(req.session.data || []);
// stored in memory ?
// res.send(data);
})
.listen(80);
----- EDIT -----
To add new data and return it in a single request, just send your array in the POST response:
.post('/data', function(req, res){
// store in memory
data.push(req.body);
// send it back, updated, in json
res.setHeader('Content-Type', 'application/json');
res.send(data);
})
There is an assumption: you should call your post with an ajax call, and not a regular HTML form. Please refer to jquery.Ajax doc to get the parsed server result.

Categories

Resources