Check out a free preview of the full A Tour of JavaScript & React Patterns course

The "Proxy Pattern" Lesson is part of the full, A Tour of JavaScript & React Patterns course featured in this preview video. Here's what you'd learn in this lesson:

Lydia demonstrates how the proxy pattern is used to intercept requests to a targeted object and decide whether or not to forward on those requests. Proxies make it easy to add functionality such as validation, logging, formatting, notifications, and debugging.


Transcript from the "Proxy Pattern" Lesson

>> So normally, when we use objects, I'm just going to make this big, I don't know if it's annoying when this repeatedly goes on, I can just always just pause it, [LAUGH] if this is like overwhelming. But, yeah, normally when we use an object, or we want to access properties on an object, we can either use dot notation like we did here like personal name returns John Doe.

Or when we want to modify it we can do that instantly as well with dot notation or with bracket notation. Now, with the proxy pattern, we actually use something called a proxy, which is kind of an object that sits in between that intercepts those requests and also intercepts those responses.

So instead of directly changing the volume person here, we actually go through that proxy which invokes the set method on that proxy. And then the proxy forwards that request to the target object same with get. Now luckily, in JavaScript, it's pretty easy to use proxies because JavaScript has a built in proxy object to use the proxy pattern.

Now, the syntax is kinda like the following, so this is kind of related to this person here. So if we had a person object, the proxy could look something like, new proxy and then the person would just the target object. So that the object that intercept the request to forward the request to or get the responses from.

And then by default, the proxy object has a lot of built in methods. Now two of them are getting set, those are the only ones that I'll cover right now. But you can just go on MDN and see all the all the methods that are available now. And then again, they also get our arguments properties.

So the first one is, again, target, so that's a target objects and then the property that we wanna get in case we use gets or that we wanna set if we are modifying a property. And also the set has a value which is the new value that we're changing that property to.

So for example here, if we have this person again, I don't know if I should make this bigger or not, I'll do that. So we have a person called John Doe. And then we create a new person proxy, which takes that person objects. And whenever we change it, so whenever we want to retrieve a value, maybe we do like person, we get the value of name is John Doe.

Or we wanna set a property, maybe want to increment the age, it's like changed age from 42 to 43. So I'll just, I can show you either in StackBlitz, I know, I also have it here, but I can just show it in the browser. So we can say like

And then you see that it looks like the value of name is John Doe. So this is super nice because it actually just executed this Get method here. So if we're like changing a value, maybe a personProxy.age +=1, is like change age from 42 to 43, so this is super nice.

Yeah, so here you see that we're using the target prop, we're still using this bracket notation here. But there's actually another built in method that we can use in JavaScript namely reflect. So instead of writing it here, the target property or target a property equals value and then returning true we can just use that reflect to get and reflect to set.

Which I find a lot easier to read and they do the exact same thing. So with a proxy, it's super easy to add functionality to a certain object. Maybe every time that we're changing a value we want to, I don't know, send something to analytics like, hey, this is now changed.

Or the more I think useful case of proxy is to add validation. I often use it for validation when I wanna make sure that if we're changing a property, it's either always string if it's a username. Or it's a number when we're changing the age or maybe the age shouldn't be lower than 18, all those things.

It's also super easy to log things like we just saw with this one, every time we accessed it, we sent a log to the console with the value that we changed. So if you ever need to debug anything, this is definitely a super nice way to do that to see what are we changing?

What is the target object? And what are we changing it to? Now of course, like a big trade out, or at least something to keep in mind is that those methods run every time they interact with the target object. So if you have a pretty long execution of those things, maybe, like I said before, we send it to analytics and this takes, I don't know, even just like one second to send there.

This could definitely lead to performance issues cuz we don't wanna have to wait every time we interact with an object, it has to be instant. But there's so many things you can do to make sure that it still goes faster like, it's asynchronous, all those things. So that's not too big of an issue but definitely something to keep in mind.

So every time when we interact with target object those methods run, so make sure to keep them small and fast. Okay, so to get started, [LAUGH] okay this looks a bit scary, but it's not. So to get the exercise about the proxy, what we have here is that we have an object and we want to add some validation to it.

So you can see the validation requirements here. So the user name has to be a string that only contains two letters, so it cannot be a string that's 1, 2, 3, hello or something and it needs to be at least three characters long. The email also has to be a valid email address.

Now I've already add some validators to this file so you don't need to like validate it yourself. You can just like invoke that is valid email function. Also there is all letters for the username to make sure that it only contains letters. And for the age, has to be number at least 18.

And to add some logging to it, so not just validation but also logging. You should change the output to include the dates when it was logged and then the value of that property is this new property or forget, so the value of this property is this value. I just have like a quick example here.

>> Could you restate the best use cases of proxy pattern again?
>> Yeah, they're are certain, so we have validation logging, formatting notifications and debugging. But for me, the most useful one is definitely for validation like we do in this exercise. If the object that we are interacting with, if we modify it and we have to make sure that it always has certain data types.

Maybe because our database expects it, so when you need it to be string it needs to be a number. We wanna make sure that we cannot accidentally change it to an invalid type. Of course with TypeScript that's a bit harder, which is great with TypeScript. But this is a much better way to do that at runtime to make sure that, yeah, we don't change it in any unexpected ways.

I've got it, yeah, I also like it for just logging, like I said here, if you ever need to know the time at which something was logged, you can just add that to the get method here. Like we did like the value of prop, maybe we just, yeah.

In this exercise, we're adding a new date, so you will see the outcome of that.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now