GET/POST methods on Express - javascript

I am configuring a server using express.
My question has nothing to do with the project itself because it is running great.
I just have a minor doubt about why I have to use GET when for me it makes more sense to use POST.
So, for short I am configuring an API key on the server side and fetching it on the client side so I can use it.
This is the snippet on the server side:
const apiKey = process.env.API_KEY;
console.log(`Your API key is ${apiKey}`);
const dataObject ={};
app.get('/api', (req,res) => {
res.send({key: apiKey})
})
app.get('/all', sendData = (req,res) => {
res.send(dataObject)
})
app.post('/addText', (req,res) => {
let newEntry = {
agreement = req.body.agreement,
subjectivity = req.body.subjectivity
}
dataObject = newEntry;
res.send(dataObject);
} )
And then on the client side I fetch on the '/api' path:
const getApiKey = async () => {
// Getting API key from server
const request = await fetch('/api');
try {
const data = await request.json();
console.log(data);
return data;
}catch(error) {
console.log('ERROR', error);
}
}
Ok, that's working and everything, but my question is:
On the first GET on the server side, I understand that I am sending the API key to the '/api' path so that I can retrieve this key with fetch on the client side. But if I am sending the api key to this path, why am I using GET and not POST?
Sorry if it seems a stupid question but I am having a hard time understanding the GET method.
Thanks!

You are not sending any API key to the server. The server is sending the API key to the client as a response. The client uses a GET request to get the API key from /api. The names of the methods (GET, POST, PUT, DELETE, ...) are from the perspective of the client.
"And then on the client side I fetch on the '/api' path:" No. First the client sends the request with
const request = await fetch('/api');
try {
const data = await request.json();
console.log(data);
return data;
}catch(error) {
console.log('ERROR', error);
}
This triggers the callback in
app.get('/api', (req,res) => {
res.send({key: apiKey})
})
and the server sends the response.

This code returns the API key from the server. It does not send it from the client to the server.
app.get('/api', (req,res) => {
res.send({key: apiKey})
}
The
res.send()
Function is constructing the response returned by the server to the client.

Usually, you use the GET method when the client has to read some data from the server, in this case, you want to read the API_KEY defined in the server. GET has no body, but every request may be parametric by passing parameters in the query string.
On the other hand, when you have to update or create an entity on the server, that's when POST (or PUT) enters into action. Here you pass your data in the body of the request.

Related

SOCKET.IO: Access cookies from devtools. Express-session

Why can't I access this cookie?
When the user logs in the cookie is recieved and sent back to the Express server.
When initializing a new websocket to the Socket.io server this cookie does not get sent, so I was trying to get it via the document.cookie. However, it did not work since the the cookie was not modifiable.
It is an HttpOnly cookie that cannot be accessed via client-side Javascript.
In other words: The server is able to read and manipulate the cookie. The client receives it and blindly sends it back with every subsequent request, without being able to read or manipulate its contents, at least not with Javascript means.
The official website did something that did not work for me.
express session middleware
const session = require("express-session");
io.use(wrap(session({ secret: "cats" })));
io.on("connection", (socket) => {
const session = socket.request.session;
});
So, I got around it by making:
Logic:
Before establishing websocket, request credentials to express endpoint "/userCredentials"
and then use these credentials to establish the connection
Warning: Down below code is stripped because I did so many auth logics
CLIENT:
...
useEffect(() => {
(async() => {
const pending_creds = await fetch("/userCredentials");
const creds = pending_creds.json();
const ws = io({auth: {creds}})
setSocket(ws)
})()
}, [])
...
SERVER:
...
app.get("/userCredentials", (req,res) => {
const userSession = req.session.user;
res.json(userSession)
})
...
io.use(socket, next){
const creds = socket.handshake.auth.userSession;
if(creds){
next()
} else {
socket.disconnect()
}
}

Send 1 request, Receive 2 Responses GraphQL

I want to trigger a request from an Apollo Server during (and dependent on the data returned from) a request that originated from the client. I want to return the data that was originally requested by the client, and later return the data from the request originating from the server to the client.
SERVER:
async function getPlaylistItems(playlistId) {
const url = '... external api endpoint with query parameter playlistId=playlistId'
const response = await axios(url, { method: 'GET' });
// response.data = ['title1','title2',...]'
const secondUrl = '...another external endpoint with response.data as query parameters'
// create a new request (but don't wait for it to resolve) and return response.data to client
const secondRequest = axios(secondUrl, { method: 'GET' });
return response.data
}
CLIENT:
const playlist = getPlaylistItems('playlistId');
const secondRequestData = ...?
I want to receive the response from getPlaylistItems first, and send the response from secondRequest (on the server) back to the client once it resolves.
Here is a diagram of the desired data flow:
The features you are looking for is #defer directive. But right now it is under development and not possible to use it using apollo-server.
As far I know you there is no support available for returning partial response right now.
Or else you can use GraphQL Subscriptions if you really want to return the partial response.
More info about #defer

Headers not set node.js api push notification

Hello im trying to set up push notifications for my webapp.
I'm getting my subscription like I should.
It saves it to my database correctly.
It sends my notification like it should if there only is ONE user in the db
and i want to send to more than only one user :)
Im using:
Vue.js (framework)
Axios (post)
node.js (api)
mongoDB (database)
Here's my post to API.
await axios({
method: 'post',
url: 'API',
data: {
subscription: JSON.stringify(subscription),
storeId: storeId
},
headers: {
'Content-Type': 'application/json'
}
})
It registreres my post, but then i get an throw error.
that "Can't set headers after they are sent."
I'm using CORS in my app like this:
const cors = require('cors')
const app = express();
app.use(bodyParser.json());
app.use(cors())
app.use(morgan('combined'))
The way I'm handling the post from my website is by finding my subscriptions and then map through and say foreach subscription
webpush
//subscribe routes
app.post('/pushNotification', (req, res) => {
var storeId = req.body.storeId
res.setHeader('Content-Type', 'application/json');
console.log(storeId)
if (req.body.storeId != null) {
console.log('Test1')
//get pushSubscription object
//create payload
const payload = JSON.stringify({ title: 'push test' })
Push.find({
"storeId": storeId
},
'subscription', function(error, response) {
console.log('Test2')
console.log(response)
response.map(item => {
res.status(201).json({});
console.log('Test3')
var subscription = item.subscription
console.log(subscription)
webpush.sendNotification(subscription, payload).catch(err => console.error(err));
})
})
} else {
res.send("failed")
}
})
As i can read around somewhere is it im not setting headers or something right. I have used cors like in tutorials and stuff.
So it's like it is crashing because it iterates wrong.
but i can't see how.
ERROR MESSAGE:
Thanks in advance
you are getting this error because res.status(201).json({}) has already set the headers and sent back the response to the client but webpush.sendNotification also trying to set the headers.You should use only webpush.sendNotification(subscription, payload).catch(err => console.error(err));
res.json([body]) sets the corresponding header and sends the result:
Sends a JSON response. This method sends a response (with the correct content-type) that is the parameter converted to a JSON string using JSON.stringify().
So, first of all you don't need to set header manually.
second, If the response has more than one item, since you can't send multiple result for a request, you shouldn't use res.json in a map.
Moreover, be aware of webpush.sendNotification that it may send a result too.

Node gRPC: sending metadata from server to client without error

From the client side, it is easy to add metadata for the server:
const meta = new grpc.Metadata();
meta.add('xyz', 'okay');
stub.service.Rpc(request, meta, (err, response) => {
});
The above can be accessed on the server like this:
call.metadata.get('xyz');
Now, if we need to send metadata from the server to the client, we do this:
const err = { code, details };
const meta = new grpc.Metadata();
meta.add('...', '...');
callback(err, null, meta);
Note that we are passing error, and the actual response is null.
How do I pass a null error and a non-null response, along with metadata?
If I do the following, it does not seem to work as there is no way to access the metadata on the client without the error.
callback(null, r, meta);
// `r` is some response message
Does gRPC spec explicitly disallow sending metadata from server to client when there is no error?
Also, while we're at it, I'd like someone explain how do we send trailing vs initial metadata from server to client in Node.
Relevant links:
https://github.com/grpc/grpc-node
Can I send a custom Error message from server to client GRPC?
How to add metadata to nodejs grpc call
https://github.com/grpc/grpc/issues/9053
https://medium.com/compli-engineering/grpc-nodejs-using-jwt-authentication-b048fef6ecb2
ServerUnaryCall.sendMetadata(responseMetadata)
server:
const method = (call, cb) => {
// code
call.sendMetadata(metadata)
// code
}
client:
const call = client.method(params, cb)
call.on('metadata', (metadata) => {
// code
})
Looks like you can use such code:
client.someFunction().on('metadata', (meta) => { /* any code */ })
At least on v0.9.x you can see: https://github.com/grpc/grpc-node/blob/v1.9.x/packages/grpc-native-core/src/client.js#L562

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

Categories

Resources