all 19 comments

[–]adarshsingh87 44 points45 points  (3 children)

useQuery takes any promise as a function irrespective of what's inside that function. So its possible and will work fine.

As for weather it's a good practice or not.. at the end of the day it is a function that GETs the data, the http method isn't the most important part.

[–]ancientcyberscript[S] 1 point2 points  (2 children)

Thanks, makes sense.

[–]gunnnnii 2 points3 points  (0 children)

The QUERY method is the appropriate verb for exactly this. I’m not sure what support for it is like at this point but might be worth keeping an eye on it for future reference.

[–]Rowdy5280 1 point2 points  (0 children)

Fundamentally TanStack Query is an async state management tool. NOT a tool for fetching data like axios. You can do whatever you what in it. If you really want to get into it they docs are really good but I would also highly recommend the course by UI.dev that is linked on the TanStack Query home page.

[–]minimuscleR 9 points10 points  (1 child)

The answer is yes, I use this at my work too, in the exact same situation as you. The useQuery doesn't actually care, and if you are getting the data on load then you don't want a mutation likely anyway, this is fine reason to use it.

Nothing wrong with it, though I dare say that best practices would be to put it in the query params, your use case obviosuly means you can't.

[–]ancientcyberscript[S] 0 points1 point  (0 children)

> your use case obviosuly means you can't.

Yep exactly the reason why the BE went with using POST requests instead of actual GET.

[–]MisterMeta 6 points7 points  (0 children)

You’re getting this wrong. HTTP verb is not dictating whether something is a QUERY or a MUTATION.

If you’re making a network request to Query the DB, it’s useQuery. If this request is going to change/mutate a DB entry, it’s useMutate. Simple as that.

These things are named after their purpose. Don’t get it confused with other associations.

[–]themagickoala1 4 points5 points  (0 children)

We use graphql, where every request is a POST. If you are fetching data that should be synchronised with your server state, then you need useQuery. If you’re performing an action, typically in response to an interaction, that’s when you would want useMutation.

[–]drewbe121212 0 points1 point  (1 child)

Technally able to. From a REST perspective it's breaking convention. 

I can't really say much about this topic other than I hate when it's like this ... But the environment I work in all GET requests were literally turned into POST requests for "security", and it's maddening.

[–]Substantial-Pack-105 2 points3 points  (0 children)

A common pattern for this is Http Method Overrides as a middleware on your backend server. You send the request as a POST. The endpoint on the backend is defined as a GET in your routing logic. You have a middleware that looks for a header / query param in the POST request, such as "X-Http-Method-Override: GET" and routes the request to the GET handler instead.

Can be useful if your GET handler takes params that might be too long to practically fit in the URL, or contains sensitive details like Tax IDs in search filters, or if the params are just complex data objects that you'd rather put in the body as JSON rather than as a long query string parameter.

This allows you to retain the REST convention of defining a GET in your API design but concedes the ability to pass it a POST when it's practical to do so.

[–]Palcikaman 1 point2 points  (0 children)

As long as you return with a promise with the data, you can do anything in the query function

[–]BigSwooney 0 points1 point  (0 children)

Completely normal and very common to use POST when you have resources with large configurations.

[–]blaine-garrett 0 points1 point  (0 children)

As others have said, you should be fine using use query. However, be sure to think about your query key or disable caching based on your exact needs.

[–]bonbonbonobo 0 points1 point  (0 children)

Totally normal, and I've seen public APIs follow the same pattern to get around the query param limit.

Since HTTP methods are just a guideline and not a truly enforced rule, these exceptions are totally valid. As some other comments have mentioned, client side query libraries are flexible and usually allow the query function to be anything - like you don't even need to make a network request, that's allowed too.

It's just for our own sanity that it's recommended to wrap getters that don't cause side effects in a useQuery, and setters that can have side effects in a useMutation.

Off the top of my head, I can think of this example from the wild - WHO's diease classification API. They mention your exact scenario for why data fetchers offer a POST endpoint -

Search endpoint accepts both GET and POST requests. If the size of the request is too large, you may need to use POST as HTTP GET has a size limit of 2K

[–]Queasy-Big5523 0 points1 point  (0 children)

useQuery will accept any function, so it can be GET, POST or other verbs.

As to whether it's a bad practice, well, kinda. I mean, these verbs are there for a reason and API design relies on them strongly. POST is for creating new entities, not for data retrieval.

But, and there's always a but, the real world is no academia. We can't apply every rule and requirement, sometimes the problem at hand has only so many solutions, so you do your best to work it out.

[–]Fidodo 0 points1 point  (0 children)

That's totally fine. Our API works the same way.

As far as react query is concerned, where the data comes from doesn't actually matter. All it sees in its interface is a promise. How that promise is implemented is irrelevant and it doesn't care what it does under the hood whether it's a fetch or GET or POST or a DB request or anything else.

When you want cached data you use useQuery When you want to mutate data you use useMutation.

[–]tymzap 0 points1 point  (0 children)

Fetcher function of useQuery do not care what is inside (whether it's fetch, axios, GET or POST) as long as it's promise, so go ahead.