How to handle redirects without setting window.location.href
?
Right now, there’s a pattern of doing:
sendHTTPRequest("POST", "/login/", {})
.then((_) => {
window.location.href = "/";
})
.catch((err) => { console.error(err); });
Isn’t this something that the server can do? In response, why not issue a redirect?
Installing
http-status-codes
for more legible status codes.
This issue does not happen when I issue a GET
request to /logout
by
clicking on a <a href="/logout">Log Out</a>
. The server responds with
a 303 (See Other)
to /browse
, and the browser loads /browse
in the
tab. If I do the same with fetch('/logout', { method: 'GET' })
instead, then the browser does not navigate the page to /browse
despite the /browse
response being observable in the Network tab. The
consensus online is that fetch
responses do not lead to automatic
browser navigation.
Re: fetch
vs. XMLHttpRequest
. The latter is the older way of making
HTTP requests from JavaScript without leaving the page; it is based on
events. fetch
is built around promises, which are considered the
preferred way of doing asynchronous operations. fetch
and
XMLHttpRequest
are implemented by browser vendors. On top of these, numerous libraries exist, e.g., Fetch polyfill
,
isomorphic-fetch
, axios
, jQuery
, etc., to fill various gaps, e.g.,
different syntax, varying browser support, etc.
Typing the Client/Server Interface
One source of bugs is the server and the client being out of sync w.r.t.
the shape of the data being exchanged. Granted, I have both the server
and the client in the same repo, how can I avoid mismatches in data?
Is
there a library or a standard way of creating an interface for my api
endpoints? :
typescript
floats tRPC
, GraphQL
, OpenAPI
, and some others, with tRPC
coming
in first and GraphQL
as the incumbent.
GitHub Copilot can help out here with quick intros on what tRPC
and
GraphQL
entail. With GraphQL
, the client can strongly type the API,
define the data payloads, fetch all the data in one request, query for
supported types, and subscribe to real-time updates. GraphQL
is
intended to be an improvement over REST
. tRPC
is designed with
TypeScript in mind. Advantages of tRPC
include no schema syncing as
the input/output is inferred directly from function signatures, and can
work with GraphQL (or any other data fetching method). In the case of my
app, using tRPC
involves replacing Express
routes with tRPC
procedures. Trying tRPC
!
Impressed by Copilot. Definitely saved me time on this one.
What’s the use case for tRPC
for endpoints that return a static page
in response to a GET
request? Copilot says that serving HTML files
should be left to traditional web frameworks like Express
as those
have built-in support for SSR of HTML.
Adding tRPC endpoints that don’t need
authentication
was mostly mechanical. However, there were a few gotchas. Some
methods/props on a Mongoose
document (e.g., the Document
interface)
cannot be shared between the server and the client, and so we need to
define a safe interface that can be inferred by tRPC
and availed on
the client side. We also encountered a
challenge in typing the inputs, given that the app relies on Mongoose
validation that occurs after tRPC
has seen the inputs. Ended up adding
a passthrough input parser, e.g.,
export const authRouter = router({
registerUser: publicProcedure
.input((params: unknown) => params as RegisterUserAndPasswordParams)
.mutation(({ input }) => {
return registerUserAndPassword(input);
}),
});
The docs are not explicit about
this because not validating is considered unsafe, and the tRPC
maintainers don’t want to advocate for it. With the base knowledge from
non-auth endpoints and reading the docs several times,
adding
auth-dependent
endpoints
integrated nicely with Express
’s session management.
References
- 304 Not Modified - HTTP | MDN. developer.mozilla.org . Accessed Apr 19, 2024.
- javascript - Difference between fetch, ajax, and xhr - Stack Overflow. stackoverflow.com . Accessed Apr 19, 2024.
- AJAX/HTTP Library Comparison. www.javascriptstuff.com . Feb 3, 2016. Accessed Apr 19, 2024.
- [Next.JS] x.data.user is of type 'unknown' · trpc/trpc · Discussion #3661. github.com . Accessed Apr 20, 2024.
- docs: Howto add typed input (without validation) · Issue #3339 · trpc/trpc. github.com . Accessed Apr 20, 2024.
The
304 Not Modified
response is sent when there is no need to retransmit the requested resources. In this case, the page at/home
has not changed, and the browser can use the cached version. If the content had changed, then the browser would have requested the resource from the server, resulting in a 200 response.