0

I have a React component that has to do a find({}) query with two parameters to a MongoDB database.

const likes = await Likes.find({ postId: postId, userId: userId }).exec()

As Mongo code only works on the server I have to make an API call (I'm using NextJS). This API call is obviously a GET request. How do I pass 'postId' and 'userId' to the get request using SWR (or fetch)?

I was trying to pass them as an object through the 'body' but I don't think this is the correct way at all.

const likesPerUser = {
    postId: postId,
    userId: userId
}

const docs = await fetch('/api/likes/user', {
    method: 'GET',
        headers: {
            Accept: 'application/json',
            'Content-Type': 'application/json',
        },
    body: JSON.stringify(likesPerUser),
})

I don't have access to the URL query string

I have a feeling I may be way off key here. Any help would be very much appreciated. Cheers, Matt

Ray Purchase
  • 681
  • 1
  • 11
  • 37
  • Normally, one does not use body with a GET request. Is it possible for you to modify the server-side, and change the GET to POST? – VedantBang Aug 06 '21 at 10:34
  • Yes, sure, but I'm relatively new to API calls and I thought POST requests were solely for creating or updating a post? – Ray Purchase Aug 06 '21 at 10:41
  • Agreed, semantically, POST requests are used for creation. But many devices/frameworks/architectures don't support bodies in GET requests. Therefore, it is safe to use a POST request while using bodies. If you must use a GET request, it is recommended to use query parameters. – VedantBang Aug 06 '21 at 10:51
  • @VedantBang: Changing GET to POST just so that it would feel better to use body isn't correct approach... It doesn't really hurt, whatsoever, to have your GET request sent with body – AdityaParab Aug 06 '21 at 10:59
  • @MattHeslington: Why do you say you don't have access to query string? If you pass your data as query string, you'd have access to it – AdityaParab Aug 06 '21 at 10:59
  • https://stackoverflow.com/questions/978061/http-get-with-request-body – VedantBang Aug 06 '21 at 11:00
  • @AdityaParab do you mean a query string to the API (sorry if it's a stupid question). If you do, then yes of course I do have access to that. – Ray Purchase Aug 06 '21 at 11:18
  • Yes... You'd need to address it at two places... First when you make your ``fetch` call, add your data as search parameters to the URL.. `http://yourhost?postId=123&userId=4` for example... And modify your server to look for url search parameters instead of pulling your data from body – AdityaParab Aug 06 '21 at 11:21
  • Refer to this answer for modifying your fetch call https://stackoverflow.com/questions/35038857/setting-query-string-using-fetch-get-request – AdityaParab Aug 06 '21 at 11:22
  • on server: https://stackoverflow.com/questions/6912584/how-to-get-get-query-string-variables-in-express-js-on-node-js – AdityaParab Aug 06 '21 at 11:22
  • Jesus, people treating the way they program like a religion. Nobody cares if you either use a POST with body or query strings, both is correct. – fabian Aug 06 '21 at 11:32

2 Answers2

5

Solution with Query Params

You can pass your parameters as query params in your GET request URL.

Here is the format of a URL that has multiple query params:

http://localhost:8000/api/likes/user?postId=xyz&userId=123

Here, you can see the ? symbol which indicates that query params have been started. And, you'll also notice & used for separating multiple query params. This way, you can send as much as query params you want.

Note: All query params are string. Query params size can be maximum 1024 characters in your URL.

Here is a sample code for receiving query params from the node.js backend:

exports.sampleFunction = async (req, res) => {
    const postId = req.query.postId
    const userId = req.query.userId

    // write your code here
}

Here is a sample code for sending the query params from the front-end using fetch:

const docs = await fetch(`/api/likes/user?postId=${postId}&userId=${userId}`, {
    method: 'GET',
        headers: {
            Accept: 'application/json',
            'Content-Type': 'application/json',
        }
})
Shariful Islam Mubin
  • 2,146
  • 14
  • 23
  • 1
    "Sending body/payload in a GET request may cause some existing implementations to reject the request — while not prohibited by the specification, the semantics are undefined. It is better to just avoid sending payloads in GET requests." https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/GET, saying that " GET method doesn't have a body", while the semantics are undefined could be a little bit confusing. Remember that these are just specifications(!) and a GET request CAN have a body, it is just not intended(!) to have one. – fabian Aug 06 '21 at 11:40
  • Yeah, you're right. But, the same documentation also mentioned that **Request has body ---- No**. That's why I wrote GET method doesn't have a body so that, we can only focus on one strategy. And, fetch API also throughs an exception if we send a body with GET request. Yeah, it's confusing sometimes with the documentation! – Shariful Islam Mubin Aug 06 '21 at 11:44
  • I get your point, totally, but saying that "So, you cannot pass body by calling a GET request." is just wrong because that not hows this works, same with Headers. **Of course MDN writes "Request has body ---- No" when they describe a specification and the browser console, which is build with the specifications, throws an error if you don't comply with these specification. But the problem is, that a specification is and will always only be a specification**, try to run a GET with Body Request in Postman and it works fine because it doesn't care about specifications, same with headers. – fabian Aug 06 '21 at 11:53
  • Yeah, I understood. So, I just updated my answer! You can have a look now. – Shariful Islam Mubin Aug 06 '21 at 11:55
  • Thank you, I am not trying to one-up you or something like that btw, but we have to be careful with choosing words with these kinds of things, especially specifications. If people build software and treat specifications not as guidelines but as a feature, they could have big security vulnerabilities in their software. – fabian Aug 06 '21 at 12:03
  • You're right. Anyway, thank you for noticing it. – Shariful Islam Mubin Aug 06 '21 at 12:04
  • Many thanks @mubin986 and everyone else involved, much appreciated and very interesting – Ray Purchase Aug 06 '21 at 13:44
1
let options = {
method: 'GET',
headers: {accept: 'application/json', 'content-type': 'application/json'},
body: JSON.stringify({
    your data parameters 
}), };

fetch('url link', options)
.then(response => response.json();)
.then(response_json => {
    console.log(response_json);
})

OR also set query parameter in your url like this. http://localhost:8000/test_data?postId=xyz&userId=123

kiran_ray
  • 289
  • 2
  • 10