Welcome back! In the last lessons, you learned how to use guards to protect user data and how to log API activity with interceptors. Now, let’s focus on a common challenge: protecting admin-only endpoints in your API.
As your API grows, you will likely have several endpoints that should only be accessed by admins. If you add guards and role checks to each of these endpoints one by one, your code can quickly become repetitive and harder to maintain. In this lesson, you will learn how to make this process easier and cleaner by creating a custom decorator called @AdminOnly().
By the end of this lesson, you will know how to use this decorator to protect admin-only routes in a simple and reusable way.
Before we dive in, let’s briefly remind ourselves how our API is set up and how guards are used. In previous lessons, you saw how to use guards to check if a user is authenticated and if they have the right permissions.
Here’s a quick example of a controller method that uses guards and role checks:
In this example:
@UseGuards(AuthGuard('jwt'), RolesGuard)checks if the user is authenticated and if they have the right role.@Roles('admin')makes sure only admins can access this endpoint.
While this works, repeating these decorators on every admin-only endpoint can make your code messy and harder to update.
To solve the problem of repeating guard and role logic, you can create a custom decorator called @AdminOnly(). This decorator will combine all the necessary checks into one simple line.
Here is the code for the AdminOnly decorator:
Let’s break down what’s happening here:
applyDecoratorsis a helper from NestJS that lets you combine multiple decorators into one.UseGuards(AuthGuard('jwt'), RolesGuard)applies both the authentication guard and the roles guard.Roles('admin')ensures that only users with the admin role can access the endpoint.
By wrapping these checks into a single decorator, you make your code much cleaner and easier to maintain.
Now, let’s see how you can use the @AdminOnly() decorator in your controllers. Here are some examples from the Books, Users, and Admin controllers:
What’s happening here?
- Instead of repeating multiple decorators, you now use just
@AdminOnly()to protect admin-only endpoints. - This makes your controller methods much easier to read and maintain.
- If you ever need to change how admin access is checked, you only need to update the
AdminOnlydecorator in one place.
Example output:
If a non-admin user tries to access an endpoint with @AdminOnly(), they will get a response like:
If an admin user accesses the same endpoint, they will get the expected data.
In this lesson, you learned how to simplify your code by creating a custom @AdminOnly() decorator. This decorator combines authentication and admin role checks into a single, reusable line, making your controllers cleaner and your code easier to maintain.
You are now ready to practice using this decorator in your own API endpoints. In the next exercises, you will get hands-on experience applying @AdminOnly() to protect sensitive routes. Great job making it this far — keep up the good work as you continue to build secure and maintainable APIs!
