In/Out Middleware Explained (C# ASP.NET Core & JS Examples)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
everyone in this video I'm gonna teach you everything you need to know about Middle where we're gonna start slowly by learning about a few functional programming concepts which are the core to knowing how middleware works and then we're gonna build our own pipeline which is gonna be quite an exponential increase in difficulty from the beginning but once we get there we'll essentially relax with looking a little bit at the ASB neck or middleware how they do it at the HTTP client middleware we'll look at that we'll take a look at some interceptors for Axios and the angular HTTP client and we'll also just for fun do the same middleware pipeline that we're gonna implement in c-sharp but in JavaScript okay just for fun all right so c-sharp middleware tutorial we're gonna start with learning about some functional programming paradigms and essentially the first one is that we can treat a function like a variable okay so the way we store a number we can store a function as a variable okay so that's the primary concept that we're gonna try to get around today and why do you want to store a function like a variable well first of all let's go ahead and create a function that we can execute write public void first function where we are going to say that executing first function and let's go ahead and dump this we're gonna be outputting it like so by the way if you don't know this program this is called link pad I'm gonna leave a link in the description if you want to go ahead and download well essentially we have a function it's called first what we want to do then is let's say this is a completely unnecessary but let's go ahead and just wrap this with start dump this and then we also want to know when this function ends okay so when we output this we can see when the function starts and when it ends let's say we have a second function okay and we're gonna look at the second function that is executing we're gonna copy this and let's put it down here and let's say we're now going to do the same but with the second function alright so we start an end and start an end so the whole thing about programming is we are trying to alleviate repetition a lot of repetition is bad and you're essentially repeating yourself you're doing double the work you don't want to be doing double the work you want to work smart the primary repetition is that a function is wrapped with a start and ends okay so this is where we want to pass a function as a parameter into another function essentially wrap some work in another work right so function is something that you're going to do and let's say every time you do this thing you also want to do this thing but then let's say maybe you're gonna do that thing but before you do that thing also do this thing okay so let's go ahead and just say that we want to wrap and what we're gonna do is grab this right here we're going to replace this with a function okay and because we're gonna be passing it as a variable we're gonna use lower case but we don't have it here right and the way you invoke a function is you call the parentheses so how can we pass the function as a parameter into this function there are two ways there are there is the old way with using delegates which is essentially like an interface for a function okay so we can create a public delegate and delegate it's basically an interface alright butter for a function alright the same way that you create an interface this is you're creating a interface for a function and then you specify the signature of the function so the signature of the function is how many parameters do they have and what return type is right so return type is void to wrap we'll just call it to wrap because I'm going to leave in this in a second and it passes no parameters okay so now we essentially created a interface to wrap for a function so what we can do is we can say that we're expecting a to wrap in here and this is going to be a function that we can execute so what we're expecting to do now is we're expecting to be able to pass these functions into here and the reason we can pass them is because the to wrap interface says that this function that is just an interface for a function it's just named to wrap it says that we're expecting a function with a signature that has no parameters and that returns a void okay so let's go ahead and call wrap on the second one first here and then we're gonna pass second right and this works because we don't call this function we just pass it as a parameter so it's just the name of the function and that basically passes the function as the parameter as soon as we would call the function it would execute first before executing this function meaning if it executes here it returns a void so we don't want to return void we want to return the function okay so there we go with that and now we go here pass first here let's go ahead semicolon this off and let's run this and we're at the same point right but now we essentially reduce the duplication of wrapping our function with start and ends and we can go ahead and create a dozen dozen more functions and for each extra function that we add we essentially reduce two lines of code so coming back here another way to supply a function as a parameter is to use a more newer pattern called using a type called an action it's a little bit newer and it seems to be used everywhere nobody uses delegates anymore so we no longer use delegates what we say is we expect an action and this compiles right so this works and let's say that what if we want to pass a parameter into here because what an action says is we expect a void function because there is a there is a clear distinction between a action and a function so for example here an action or otherwise known this kind of a method it doesn't return anything so there is no return type okay if we would have supplied a func of int right this means it must return an int okay so whatever we're supplying here must return in int okay and now this compiles but we're not providing a or we rather not returning so it's complaining here okay so we're not gonna be touching on these func but essentially understand the actions don't return anything so the only thing is you can fill in the action is something that returned that is void okay and if we want a signature that has a parameter so for example if we pass in an integer you can see this no longer fits so we can go ahead and add an integer here so it's a function that expects an integer so then we pass an integer into that function from the wrap where you can see this first one can no longer fit this because it basically says by specifying a type here we're stating that the signature of the function should accept an integer as its first parameter and then we can do the same for if we have more than one parameter right so string ain't now we will essentially fit we cannot swap these around so these have to be in the correct order okay so you can see it doesn't compile so that's essentially kinda it to the action we're gonna stick with the more simple example here let's go ahead and rerun this and now let's go ahead and wrap the wrap in a try okay so we're gonna create another function where we're essentially going to put the wrap function inside a try function okay so let's go ahead and try and again we're get still going to do an action and we're still gonna call it function and what we're gonna do here is a try-catch we're going to call the function and let's say that we are trying here and we're gonna catch at the end we're gonna catch an exception we're not gonna throw exceptions but we're just gonna make sure that we're catching it right so we have a little tripe so how do we put the wrap action because the signature here doesn't really match the signature for this action but what the problem here is is that if we change the signature of the try function to essentially be off type action it's essentially we're expecting a function that has a function as a parameter okay what we're doing is we're breaking a chain of these functions the ability to change these functions okay we're breaking it because the signature is starting to be different okay and that's the that's the primary backbone of the middle order to be able to change these functions to have the same signature to essentially have a function that accepts the same parameters and just have different implementations okay so let's go ahead and thread them anyway okay so we're just gonna put them into lambda expressions and then we're gonna go over why that can be a problem so for the try function let's go ahead and wrap this bit in a lambda we're gonna do the same thing here just like that let's go ahead and run this and here you can see that we are trying first and then starts executing first function ends and what we can actually do is let's go ahead and interchange these okay so you can see that the other one starts trying execute so this is kind of the thing about the functional programming is to be able to sort of switch you around change the order of your middleware that's all that middleware really is but the main problem here is at the moment this type of middleware is kind of on crutches primary crutch that I want to talk about is this lambda function so what happens when you compile your c-sharp code well it's gonna do with these lambda functions is if I drop these down what we'll do is it will say write this function right here this is actually not real and we need to convert this to an actual function to exist so what we'll do is we'll create a local function and it will just say something like lambda for first and what it will do is it will essentially say right let's just execute this here okay and it actually passes a function as parameter here all right and for the second one it does the exact same thing so second it will grab this try it will put it in here I'll grab the lambda second I'll pass it as a parameter okay so this is what it does what it does is it creates this debris so this debris is the primary crutch of our middleware right now and the primary problem of why we can't sort of chain these so what I'm gonna do is I'm gonna copy this workspace because and I'll switch between the two but essentially let's go ahead copy this and what we will do here is we're gonna add a little bit of parameters that we can use right so let's go ahead and say string message so we're gonna try to PI we're gonna try to pass message messages to these so essentially we'll have some piece of data that we want to put through our middleware right it's not just executing some functions void functions we have a carriage that we essentially we have a package that we're gonna push through the pipe and then something is gonna come out on the other end then we want to deal with that as well let's go ahead and provide some parameters and utilize these parameters so I will move this string into here just so it looks pretty and we know what function we're executing let's go ahead and save message here and then we're gonna say message here I'm gonna remove these lambdas because they don't really serve that much purpose here I'll do the try again on here and the this they don't exist and let's actually start a clean what we want to do now is because essentially the signature changed so we have to change the signature of our action as well okay so what we will try if we try to wrap our second function it will no longer happen all right so we wrap our second function it doesn't happen okay so what we can do is we can do this like this so let's just pass a number two but again with the lambda bit we are putting our middleware on a crutch essentially just remember that the lambda here is the crutch all right this is not something that we want to do especially because this number two is our package and we're not actually putting it for the wrap we can't do anything with it if it's just in this lambda function right so what we want to do is we actually want to receive our message and do something with it and then actually put it inside this function okay so once we have this message we can say that we are starting and we'll just dump the message here and then we'll pass the message I'm just gonna keep enza's ends so what happens now is we can go ahead pass the two here and still have the function with the correct signature passed here right and then we actually consume it inside the wrap function now again coming back to the middle word point is that the signatures of the middleware components kind of have to stay the same so let's go ahead and copy this signature put this here and we're gonna do the same we're gonna just pass the message here and we can say trying here and say message okay don't need to save that and now if we want to wrap this again this is where chaining this can become a problem and we will have to put this on crutch unfortunately because this signature right here doesn't match this sure for this signature we accept a message and an action here we only accept a string so this is how we would do this we would still pass the two but then we would say that in this LOM that we're gonna be essentially creating a message here and passing it here okay so the message that we're gonna thread in we're gonna put in to try we're gonna say write message once try is done you're gonna then thread it into wrap okay and this is once we execute this function here this is when it's gonna put it into the wrap but remember that the lambda is converted into a local function okay so again we're forced to use this crutch and we can try to execute this and you can see that it's pretty much working now that we're sort of at a point where we can understand that the this lambda is a crutch and and if we try to essentially build our pipe a little bit more you can imagine how atrocious is gonna look right so you can see that we have to supply a lambda here and if we go let's say one more level okay try to so we're gonna try to where we're now going to be passing the e to and here we're gonna have the message where in here we're now going to have to pass it here and the scope is going to be changing as well so this is going to be message one we're gonna have to be passing message one here and this is going to be message to where we're going to be passing message to here right so this is not ideal if you want to create a pipe like this for example the real message is here and we want to pass it into here and this is going to be our VAR pipe and I guess action string okay you can see how this is not the best not the best way to represent a pipe right so if we say pipe one all right you can see the pipe is working and we can store it as a variable but it's not the best way to declare it if you ever used callback functions this is essentially what this is this is callback function health so this is where we're essentially going to try to use object orientation and try to thread these functions through each other and here I'm essentially going to try to replicate what asp net core middlewares middleware does okay so here we are let's go ahead remove this we will still have our first function and our second function where we're gonna accept parameters as strings although it's not so important what we really want to do is we want to have these wraps and tries convert it to middleware so let's go ahead and add some structure first I'm going to create a public abstract class the reason I want to abstract class and an interface is because I want to define a constructor that should be fulfilled so we're gonna have a pipe and just line up so the primary thing that I want in my pipe is a constructor with the action and essentially what I'm gonna be doing is I will have a pipe okay and if I have one pipe in the middle where that's the end of the story I put the action in there all done if I have a second pipe what will have to happen is that the first pipe will essentially have to go around the second pipe okay and that's this function right here essentially you can see how the action is in the middle of this pipe and again the function here is in the middle of this pipe okay so it goes in and then it goes into the next pipe and then it comes out alright there's a bunch of pictures on the internet about middleware they pretty much explained the flow of this it's quite easy to understand here we're gonna really dig in here so when I create my pipe I want to make sure that it knows which next pipe to call okay so what the action is going to be is a handler on the next pipe okay and the handler is going to be this action so constructor we're gonna have an action where we're gonna accept a string and it's just going to be an action okay let's format this a little bit let's go ahead and assign this action to an action I'm just gonna create a field of action here okay so my pipe now has an action that it can use and I'm gonna give this a protected so anything that inherits from this can actually use this right this is not so important but nevertheless next thing that I want is to be able to consume the message and do something with the message so the way that we do stuff here I want to be able to do that with this message as well so what this handle will have to be is essentially a handle that will have to be that can be put into another pipe so here let's go ahead and create a public void because it's in action and we're going to consume a string right so let's say handle string message so we're going to handle a message and because this is an abstract class this is going to be an abstract function which is something that inherits from the pipe we'll have to implement okay and I don't want to save it let's go ahead and implement a wrap pipe first so let's go ahead and say public wrap and what is going to be a class pipe let's go ahead and bring in our implementation we are going to go ahead copy this bit we're missing the function well that's alright we have the action here instead right which we are going to be putting into the constructor and for the wrap let's go ahead and grab our constructor and I'm just gonna actually copy this signature here I'm gonna press it to the base okay so when I pass it to the base it's gonna be put back into here I'm gonna collapse this one here and let me just format this a bit yeah didn't really want that there okay so that's the wrap function okay with that let's go ahead and do the same for the try I'm gonna copy the wrap I'm just gonna rename a few things so try try handle stays the same action stays the same the thing that we do with the action changes okay so all we do is we implement a different handle for the middle we're okay try to doesn't need to exist okay we can create a different type of middleware if we want so we have two middle words that essentially do the same thing now what we want to do is create some sort of a builder for this pipe okay and this is what I'm gonna do and actually I think it will be a little bit easier if we look at the pipe while we build this so I'm gonna create a pipe builder where the first thing that we want to be able to do is add a pipe or register the primary thing that we want to execute do we want to execute the first or do we want to execute the second right what do we want to execute so this is something that could be done in the constructor and again the signature matches this as well as the handle matches this so again going back alright right nope not in here in here and where you see the wrap you can see how we call the wrap the handle is different from the function that we're executing here the handle has the same signature as what we're gonna try to execute okay so it's void and it has a string right so they're essentially kind of the same function they can be used in the same places but what they actually do is different all right so in here I'm gonna accept an action with a string and this is going to be action or let's call this main action let's go ahead and make a global private here main action pump so we pretty much know what we want to execute in the end by specifying this now what we want to do is be able to add pipes to our pipe builder and because essentially what's going to happen here is we can not pass instances of types so one when we create the pipe we already need to know what actions gonna be going in there okay so we need to know all of our pipes before we build the whole pipe okay so what we're gonna do is we're gonna collect all the pipes that we want to register first let's go ahead and add void add pipe and here we're gonna make sure that we supply a type of pipe all right so a type is a class that represents the type of an object so if I would type off string this essentially is going to give me a type of string right where I can go ahead and inspect all of its different properties but essentially what we want to do is kind of do a little check is this type a pipe or like let's say that it's a pipe type but so what we would do is we would say if pipe type get type info and is instance of type type of pipe so we're what we're doing here is we're essentially checking write whatever type were supplying here is it an instance of pipe because what we're doing here is we're gonna be providing types of wrap and we're gonna be checking right are they actually pipes and coming back here looks like I missed one curly bracket okay so here we're gonna just throw an exception I'm just gonna put a breakpoint here so in case I hit that I just want to be able I wouldn't want to be the first to know otherwise let's go ahead and collect all these types so let's type and pipe types okay and we can initialize this form the constructor like that new list type Slayer what we want to do here is just say five types by pipe bomb easy right we're just collecting all the types of pipes the hard bit is now essentially assembling them right which is not really too hard but it's hard if you never use the activator so every builder has a build function so let's go ahead and create a public and all it's going to be is this action that we want to return right so we want to return an action build okay right there so how do we construct a construct this function first of all let's consider that we are going to get a type from our list how do we create an instance right so of our pipe will you use something called the activator so an activator what you do is you can create an instance so you will essentially provide pipe types you will provide a type of what you want to create and then you can specify some arguments okay for the constructor for our constructor we would have an action of type string so for the last middleware the middleware that is actually going to be executing so coming back to the first example in this example the last middleware here is wrap and the last maneuver or actually here the last middle words are whichever ones in these lambdas so wrap is the list middleware the one that's actually going to execute the function that we are wrapping all together okay so here is where we're going to be putting the main action okay so if we put this in the first so let's go ahead and get our pipe which we're gonna get from our pipe builder where the action is gonna be first we're gonna go ahead and add a pipe where the type for that pipe is going to be let's say we will preserve the same original order for try and then wrap we would be doing type off tried not line up tripe and then we would add another pipe type of wrap and these aren't chainable right now because I haven't made them chainable I will need from add pipe I will need to return a pipe builder and return this okay so now they're chainable but at the end we still kind of don't get a pipe now we want to just return null here and at the end let's go ahead and just build this okay so this at the end will be the pipe so if we first add the try and then we have the wrap what we have in the list at position zero is try so if we put the main function and the try and then we have the try function which inside of it in the constructor we have passed the main action so a try function is holding the main action so if we then wherever we have the in that instance if we put it inside the wrap function the order is not preserved because it will execute the wrap function first and then the try function and then the function that we essentially wants to execute so let's go ahead and kind of turn the wheel we want to reverse the order so instead of supplying the first pipe that we want to create here we want to try to instantiate the first pipe and passing it as a parameter the second type okay so the way I'm gonna achieve this is I'm gonna create a private action string because remember the actual thing we're putting into the constructor of the pipe is a handle of another pipe okay so we want to basically create a pipe the last pipe that we add we want to grab that pipe put the main action in that pipe and then use the handle of that pipe as a parameter for the the pipe that's gonna wrap that okay so can be a little bit mind-boggling but as we work through this hopefully it will make more sense create pipe right here so what I want to do is I want an index of all my pipes I want to basically know which pipes I'm going through this is where I'm actually going to be creating these so I'm only gonna instantiate the main action when I've reached the end otherwise I'm gonna go ahead and try to create a pipe so if index equals five types count all right so I'm reaching the end of my pipes if I have two pipes the way I have now what I want to do is go essentially this on the last one so actually so now you actually won't be able to reach the last pipe here with the index being overflown so let's do a little bit different right so while the index is less than the count we're actually in range for creating basically we're in range for inserting one pipe into the other once otherwise once we're out of range we want to create we want to return the pipe with the last index I think I'll still need a minus one here let's go ahead and do that yeah so once we create the instance let's actually put this into a our final pipe because this is going to be a pipe right we want to convert it and what we're actually returning is the handle it's like that okay so this this will happen at the end before this what we want to do is start creating this pipe right here so we want to create the pipe starting at zero so we're and we're at zero and this will be 2 minus 1 will be 1 so we will be at our first one so this is where we'll hit this what we want to do is we first want to instantiate the child pipe the chat the pipe that is gonna go into this pipe so child by handle the only reason I'm calling it handle is because all we're doing in this pipe is we're returning handles right we're gonna combine all these functions I'm sorry I'm rambling on so much but I'm trying not to miss too much information I know this thing can be confusing what we're gonna do is we're gonna create a pipe because we know we will need to pass that index right there okay and this will bump it up to 1 and this is when we're gonna reach that final pipe and we're gonna return that pipe from here ok so this is a recursion i'm using a recursion here to essentially instantiate things before instantiating and other things let's go ahead and actually grab the pipe and here we're gonna use the activator and we're gonna grab the pipe types of the actual index that we're using and remember the index that we add the number to this index isn't actually incrementing this index we're just basically grabbing the next type but we're going back into this function so for the same instance occur again we're just gonna grab the next time before instantiating this pipe so essentially we are grabbing the last if I can get in range we're grabbing the last or this will be the store we're grabbing at the last pipe and then creating the last by putting into the previous pipe into the previous into the previous into the four until the very first pipe okay this is essentially what we're doing so again we're gonna use the activator to create the instance and the action that we're passing here is the child pipe handle okay and then we finally have the pipe and this is by the end this is what we would want to return we want to return the pipe handle and again we'll just need to cast this right here okay I'm not actually call it we will essentially create a pipe from the beginning and we'll have the pipe at the end and can just return this and this can be simplified the build can start with a zero and call itself embody and return the pipe but hopefully you get the picture so let's go ahead and try this thing first build pipe yep what do we want to say pipe hello world or just hello hello world's too far go ahead and run this looks like I'm hitting an exception I clearly don't know my reflection checking I'm pretty sure this is correct oh so I'm gonna remove that okay so you can see what we essentially did is create our own pipe with the middleware so now we can nicely chain these functions and that's essentially what's gonna be done in the middle where we don't have a abstract class that we inherit from in dotnet core but here what we essentially do is we give it a little bit of structure and the check there that you get performed if you have time to look up the code I don't want to you can do that but you can see that it works and type the world here we can try another one okay you can see that it's essentially middleware let's reuse it can be stored and can be declared in a reasonable manner we're not building staircases okay we're building walls all right walls of code yeah this will be it for this part let's go ahead into Visual Studio here we are in Visual Studio essentially what I did I knocked up a little example of a custom middleware component in dotnet core and we're gonna go over how to add this component to the pipeline and essentially some other possible methods we can use to actually implement middleware so take a look at this custom middleware piece some components should stick out to you and you should be able to recognize them as the middleware building blocks for example the request delegate the fact that it has a delegate on the end you don't necessarily know what function it is but since it's going to be invoked you know that it is a function if we press f12 in it we can see that it's a delegate that has a signature of returning a task and the package that we're essentially passing around is the HTTP context okay so this is what the function will expect and this is what we can return and essentially the custom middleware component the invoke function is essentially a request delicate as well right so this is pretty much the same exact solution that we've written in our link bat script right here in the custom middleware component right where we have a pipe we're going to be passing the delegate all they did is replace in the action there they put the HTTP context here and they actually made it a function by making it return a task okay and they put the HTTP context here all right but nevertheless it's almost the same thing and again the handle their signature pretty much matches here except instead of void they return a task and they here they pass the HTTP context just understanding that the middleware is a function wrapped in another function so understanding this concept will allow you to know when to use middleware okay for this reason I'm not going to be showing you any actual real-world implementations because as long as you understand this idea for when the time comes for you to actually use the middleware it will become apparent because of some use case or some functionality that you're trying to trying to implement so if we have this custom middleware piece the way we do it in our link pad script we essentially just add it to the pipe and this is pretty much the same we have our I action builder and all we do is we say right let's go ahead and use our middleware where we provide our custom middleware and this is pretty much the end of story these use routing and use endpoints are just functions static functions that have the I application builder which they extend and they're just pretty little bits of code that you can wrap your ugly use middlewares in okay so some other ways that dotnet core allows you to inject some middleware is through the use function in the middleware and there are two overloads for this so the first one that you will see is func that accepts a phone call request delegate and the returns are request delegate okay so again this is the this function here and notice that in request delegate you don't actually have access to your package so here we're gonna have a request and we're gonna return your request okay so this middleware is all about do something before request okay so this way we are essentially doing something before we execute the request but we don't have access to the HTTP context all right another bit of the use function that we have is if we go into the use and you can see right here there is one of two overloads and if I press up or down I can scroll through them so this is the request delegate this is the second one and the first one is a func of HTTP context and the func of task and it returns a task so the signature is essentially we accept a parameter of HTTP context and a function that returns the task and by the end of this we have to return a task okay so we have the HTTP context and then we have the function and what we do is we return a task but this function is going to be returning a task so essentially what we're doing is we're returning a function here so will this middleware we can do something before and then if we want to do something after all we can do is turn this lambda async and essentially just a weight on this function and then we'll have the result here and actually we can't we can just await on the function and this will be something along the lines of calling this next function but without actually passing the HTTP context it this is so this one is a little bit weird but nevertheless it is pretty much the same but just without having to pass the HTTP context into there and then we can still do something after okay so these are the options that are available to you which one to use you will know once the situation arises as long as you understand middleware you will be able to implement it so the first part is very crucial to how we implement it and again the basic concept that it's just functions wrapping other functions okay and basically another thing we can look at is the HTTP client so this will essentially allow you to inject an HTTP factory where then you can spawn a client with some sort of name and for this the one little gotcha is if you just add an HTTP client you can't get an HTTP client builder so you really want to get an HTTP client builder to get a hold of the HTTP message handler middleware right not middleware sorry function that will allow you to add a type of the middleware that you want to apply to the HTTP client so with the HTTP client it's a little bit different because here we essentially have this HTTP context that contains the request and the response okay so it's like we're passing this container with the request and the response and it's just this container going around and the HTTP client middleware we have a task of the HTTP response message but what we accept is the HTTP request message okay so we send the HTTP request message and before we actually send it again we can do something before it and we can do something after it it's the same story it's just functions wrapped in other functions you can remove the task here and just return the base here right and then you don't get to do something after this and the main difference between the this middleware and the HTTP client middleware is that we are actually inheriting from the delegating handler okay and this is what the delegating handler is primarily it wants you to implement this send async function and that's all there really is to it right again the concept is really being able to understand the concept of function wrapping another function all these implementations of middleware are actually easy to implement yourself if they don't exist if you need to wrap some sort of functionality and other functionality you can now create your own middleware because of what I showed you before but essentially this is how you would do it for the or now let's go ahead and take a look at axis and the angular httpclient and their interceptor concept so here we're looking at the axis interceptor and again the way that you can spot middleware and essentially just recognize what you've learned before is again looking for this concept of a function wrapping either another function okay so here we have Axios and what we do with Axios as we say right let's go ahead to the interceptors and we are going to go ahead and grab as the request I'm getting some github intellisense which I don't want to get but essentially for the request we want to put a pipeline on the request so here an axis we don't have middleware where we sort of wrap the request and then have access to the response at the same time we do the requests and responses separately okay so here to the request we can add a function that where we essentially get the configuration for the request we can do something before the request is sent right so again it's a similar pattern and then we return the configuration so you could simplify this to being the HTTP context okay and then the same thing for the response you provide a function where you do something after catching the response and then you keep returning the response okay so pretty familiar concept for the angular HTTP interceptor what we do is essentially we inherit from a class of HTTP interceptor and then we get a function of intercept we then have the request that we're about to make right so pretty much the same thing the primary difference between words like middleware interceptor filter is just slight functionalities that they provide but I would call it all middleware and a way to avoid confusion you're just wrapping functions that's what you're doing so you have the HTTP request and then you have the next handler so this is closer to our dot neck or middleware where we can await the next handle or grab the result and still do something after and then return that result from this handle function okay so we do something before and then we can return the handle or we can store the result in a variable and then return it after okay so this is a do before and do after Middleware okay so at this point as long as you know what middleware is spottin what you can do with the types of middle words that have been implemented in your specific language or technology right now let's go ahead and implement our own version of middleware and JavaScript so here we are in vs code with main J's file where essentially I'm gonna do something like console.log ape and run this file here okay so let's go ahead and first define our primary function that we're gonna execute and here we're going to take that example where we have a delegate that we can do something after with the response okay so it's going to be a request coming in we're going to put it in the next function and we're going to be able to retrieve their response and do something with the response okay so the first thing is I'm just going to create a function that's gonna mock out an API call alright so we're gonna be making an API call this is going to be a function where we're gonna be taking a request and we're just gonna return a hello plus the whatever we're passing okay so we have the API call let's go ahead and make a simple pipe where again we're just gonna do the start and end so again we're just gonna call this wrap this is going to be a function where we're gonna have the request coming in and we're gonna have the next function okay so we're gonna console.log start and we're gonna log the request and we're gonna do the same for the end but now what we're also going to do is we're gonna grab the response from the next function where we're gonna pass the request and we're going to be able to grab the response and then return the response in the end as well so how I'm going to achieve this in JavaScript again because this is the actual implementation of the pipe and implementations differ from one way to another this is not necessarily the most correct way but is going to achieve as the task nevertheless or the solution so I'm gonna store all my pipes in this array and let's go up and let's go ahead and create a function that's going to be adding pipes so here we're gonna be passing a pipe and what I'm gonna do is I'm gonna store every single pipe and every time I store the next pipe I'm going to put the previous pipe in it so what I want to check is if my pipes length is zero this is essentially where I know it's the first pipe coming in and I'm just gonna put the API call it and let me just convert this to a function like this what I will do is I will use the lambda function crotch to essentially mock out this next function call to essentially because the function signature here differs from the pipe signature okay so I want to sort of normalize the function signatures so for the pipes all I'm gonna do is I'm going to push a lambda function where we're going to be accepting a request and that request is what I'm going to be putting into the pipe into the first pipe and the API call is going to be the function that I'm gonna be executing in the next otherwise we are gonna use the previous pipe and put it in the to the array as a lambda function right so let's go ahead and copy this and instead of the API call we want to get the previous function so maybe not let do we get a let I'm not sure but we'll see so previous function or let's actually call it pipe and we're going to go into pipes where we can supply pipes dot length minus 1 and this is this way we get the previous pipe and now the current pipe that's coming in for the next call it's going to be this lambda function that we put put pushed in there previously okay so now what we can do is we can add a pipe rap and this is going to be pushed in first and now we can also make a try rap so let's make it try rap the reason I'm not calling it try is because try is keyword so I'm gonna be calling a try rap and again the signature is the same I'm just gonna go ahead and log trying here and I'm gonna do returning the response straight away from the next I'm not actually gonna be wrapping it in a try it's just an example okay so here we are what I want to actually do is call the try first and rap then so I will add the try rap first or rather no I need to add it after so then when we go to build the pipes we're gonna add a build function where we're just gonna return the last pipe because the last pipe is going to contain all the previous pipes we want to just go to our pipes and we want to grab the length minus one right here I actually just realized that length is going to be a outbound so we actually want to do - two - here to get to grab the previous function right so hello in my part but we didn't run this yet so they are didn't happen yet so once we build we what we get here is the last added lambda with all the previous pipes attached to know and all the pipes are contained in this pipe sorry so now what we can do is grab our main pipe by calling build and for the main pipe let's go ahead and call world okay let's go ahead and run this actually I like it completely so no nevermind this is still meant to be once so let's go ahead clear this again and let's do note okay so running our application we essentially get the triangle then we get the start and then we get the end and again we can interchange these so we can swap the order of the middleware and we can run our program again and you can see that the try is now happening inside the wrap the wrapped pipe so just another quick example of middleware JavaScript this will be it for this video hopefully enjoyed it if you did don't forget to leave a like subscribe for more if you have any questions make sure to leave them in the comments section don't forget to join the discord channel link is in the description and hopefully I'll see you in my other videos
Info
Channel: Raw Coding
Views: 29,936
Rating: 4.9372549 out of 5
Keywords: c#, asp.net core, middleware, tutorial, c# tutorial, asp.net core tutorial, middleware tutorial, asp.net core middleware, c# middleware, what is middleware, middleware explained, how does middleware work, js, js tutorial, js middleware, axios interceptor, angular interceptor, js middleware tutorial, httpclient, httpclient middleware
Id: xWWj0zGKS-k
Channel Id: undefined
Length: 54min 3sec (3243 seconds)
Published: Thu Apr 09 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.