I'm trying to wrap my head around servers and how to set up one with all the stuff I wanna use on my app.
Middlewares keep popping up... I guess it is something that gets loaded by the server in the middle of sth?? Please help!
I'm trying to wrap my head around servers and how to set up one with all the stuff I wanna use on my app.
Middlewares keep popping up... I guess it is something that gets loaded by the server in the middle of sth?? Please help!
For further actions, you may consider blocking this person and/or reporting abuse
Nina Baghdasaryan -
Ava Parker -
kelseyroche -
Amélie -
Top comments (9)
Daniel is an expert fruit juicer. Fruit is being sent to him and he makes delicious juice out of them.
One day, he was sent a container full of apples. As he was about to start his work, he noticed that some had bad spots. Bummer, he thought, as he threw these bad apples away. Another shipment of oranges come in. He's surprised to see that some were too small for his liking. Annoyed, he threw them away as well. Then the last package came in, a bag of fresh mangoes. It turns out a handful were unripe! Feeling outraged, he threw those as well and continued his work.
Weeks went on Daniel had enough. Filtering through these fruits are taking too much time. To be fair, juicing is his skill, not filtering fruits. He decided to hire John, Jane, and Jonah. John checks the incoming shipment for bad spots, and hands off the good ones to Jane. Jane checks the sizes of the fruits and gives the one that have the right size to Jonah. Jonah, lastly, checks if the fruits are ripe for juicing. Alas, Daniel receives the fruits that are prime and ready for juicing!
Daniel = Server
Fruits = HTTP Request
John, Jane, Jonah = Middlewares
PS. Idk anything about juicing so this might be a silly example lmao.
This is the best real life example of any tech thing I've ever read! ❤
This was wonderfully insightful! Thank you very much :)
so a it's a function that checks if the fruits where good for juice extraction.
Think of an HTTP request like an assembly line. The user is at the start of the line and submits the request. The server is the next person in line: it receives the request, attaches it to a (currently empty) response object, routes it to the correct endpoint, and passes it on. Then each other person in the line can alter the request and response (or not), then choose whether to pass them on, throw them away, or pick them up and throw them back to the user. Each of these other people is a middleware. At the end of the line is a person who does what the user actually asked for, whether that's fetching data, updating a database, or communicating with a third-party service. The user hopes the request will make it all the way to the end.
In Express (a popular NodeJS server framework), a middleware is a plain old JavaScript function. It does something to a request or a response, then either continues or terminates the request. For example, you might have an endpoint that looks like this:
So when the server receives an HTTP GET request at the
/api/chapters
URL, the first thing it will do is call theisAuthenticated
function, which could look like this:This is a very small middleware. It has access to the request object
req
, the response objectres
, and a functionnext
that can continue the request. We check whether the user has an authentication token (in a real-life app we would validate it somehow) and if so we continue the request, which in this case will proceed to get the user's chapters from the database and return them in the response. But if the user doesn't have a token, we redirect the user to the/auth
page so they can log in.The nice thing about a middleware is that it's separate from the logic of any other middlewares or the endpoint itself. We can use the same
isAuthenticated
middleware on any endpoint, just by adding it to the arguments ofapp.get()
,app.post()
or any other endpoint method.We can use as many middlewares as we want on any endpoint:
They're executed in order. When a GET request comes to this endpoint, Express will hand the request and response off to
isAuthenticated
, thenisPremium
, thenvalidateRequest
, thentransformRequest
, then the final arrow function. Any of these middlewares could choose to end the request (or make it time out by never callingnext()
), in which case everything will stop there--the other middlewares and the last function will never be called. But if they all choose to continue the request, the user will most likely get what they want.You'll notice that the last argument in the list--the arrow function--looks a lot like a middleware. It pretty much is! The difference is that I didn't make it a named function, since it probably isn't shared with any other endpoint. Since it's just another middleware, we could put more middlewares after it, and if it called
next()
, they would get called too. But in my experience a function like this usually callsres.send(books)
and the request ends there.Middlewares in .NET work similarly, although they're a bit harder to set up. I assume the concept is the same in every server-side language.
thanks a lot, it was exactly what i wanted to know.
Middlewares are awesome! The best way to show you is looking at this page in a popular PHP framework's docs: slimframework.com/docs/v3/concepts...
Basically, think about opening an onion and peeling back the layers til you get to the core. The core is your application and each layer is another service or layer of protection. What can you do with these layers of protection? Anything! You can check tokens, check that the values coming in are santizied, or strip them of whitespace, you can add headers to the HTTP response going out, say a Sunset header.
I actually wrote a blog post about this before:
moesif.com/blog/engineering/middle...
this is so much fun.
thanks for all the clarifying answers!
really helpful.