My guard automatically embed to another method in controller Nestjs - nestjs

I created a bookmark method that uses a JwtAuthenticationGuard and IdentifyRecipeGuard. But when I put that method under another method that uses IdentifyRecipeGuard, for some reason IdentifyRecipeGuard gets executed when I try to make a request to the bookmark method. And when I move the bookmark method right under the findOne method it works well. Why is this happening?

When a request gets processed by your server the routes will be evaluated in the order that they are defined and the first one that matches will be executed. However, because :id comes first this controller method will be used and the request will never make it to your bookmark handler.
In your example, if someone sends a request to /bookmark then both the :id route and the bookmark route are potential matches (since the framework has no way of knowing that bookmark isn't the id of something).
To fix this simply move the more specific routes above the ones that have route parameters.
This issue is unrelated to NestJS and you would be seeing the exact same issue if you were building an app with Express directly

Related

What's the difference between Interceptor vs Middleware vs Filter in Nest.js?

What's the difference between an Interceptor, Filter and Middleware in Nest.js framework? When should one of them be used and favored over the other?
Thanks
As you already implied with your question, all three are very similar concepts and in a lot of cases it is hard to decide and comes down to your preferences. But I can give an overview of the differences:
Interceptors
Interceptors have access to response/request before and after the route handler is called.
Registration
Directly in the controller class with #UseInterceptors() controller- or method-scoped
Globally with app.useGlobalInterceptors() in main.ts
Examples
LoggingInterceptor: Request before route handler and afterwards its result. Meassure time it takes.
ResultMapping: Transform null to [] or wrap result in a response object: users -> {users: users}
Conclusion
I like that the registration is closer to the route handlers compared to middleware. But there are some limitations, for example, you cannot set the response code or alter the response with Interceptors when you send the response with the library-specific #Res() object in your route handler, see docs.
Middleware
Middleware is called only before the route handler is called. You have access to the response object, but you don't have the result of the route handler. They are basically express middleware functions.
Registration
In the module, very flexible way of choosing relevant routes (with wildcards, by method,...)
Globally with app.use() in main.ts
Examples
FrontendMiddleware: redirect all routes except API to index.html, see this thread
You can use any express middleware that is out there. There are lots of libraries, e.g. body-parser or morgan
Conclusion
The registration of middleware is very flexible, for example: apply to all routes but one etc. But since they are registered in the module, you might not realize it applies to your controller when you're looking at its methods. It's also great that you can make use of all the express middleware libraries that are out there.
Exception Filters
Exception Filters are called after the route handler and after the interceptors. They are the last place to make changes before a response goes out.
Registration
Directly in the controller class with #UseFilters() controller- or method-scoped
Globally app.useGlobalFilters() in your main.ts
Examples
UnauthorizedFilter: Map to an easy to understand message for the user
NotFoundFilter: Map all routes that are not found (not part of your api) to your index.html.
Conclusion
The basic use case for exception filters are giving understandable error messages (hiding technical details). But there are also other creative ways of usage: When you serve a single page application, then typically all routes should redirect to index.html except the routes of your API. Here, you can redirect on a NotFoundException. Some might find this clever others hacky. Your choice. ;-)
So the execution order is:
Middleware -> Interceptors -> Route Handler -> Interceptors -> Exception Filter (if exception is thrown)
With all three of them, you can inject other dependencies (like services,...) in their constructor.
For those of us who "get it" better visually, I've created this NestJs pipeline digram based on the latest v6.10 version. Please feel free to point out any inaccuracies. I'll review and update it promptly, if needed.
I'm assuming that you mean Pipes instead of Filters as Filters are primarily tied to Exception Handling.
There is definitely some overlap as Middleware are a flexible way of composing any web application but are more of a generic concept (creating a stack of functions to build a pipeline). The others are Nest specific concepts and as such tie in a bit more naturally with things like Dependency Injection.
Pipes are used to transform input data (and optionally to do validation).
Interceptors are really neat because they can transform both data coming in and leaving your API. They give you the ability to mutate what the original handler would have returned through the use of observable streams. This is something that you would probably need to implement using two middlewares (on either side of the handler).
Use Pipes when you want to transform data coming in to a handler.
Use Interceptors when bi-directional transformation is required.
Use middlewares when you want to stick closer to the traditional (eg Express) way of building your web app or when you want to more broadly apply functionality to many handlers at once (there's less decorators floating around in your code).
Middleware
The usage and function of the middleware of Nest.js is basically equivalent to Express.js, which generally functions for:
execute any code.
make changes to the request and the response objects.
end the request-response cycle.
call the next middleware function in the stack.
if the current middleware function does not end the request-response
cycle, it must call next() to pass control to the next middleware
function. Otherwise, the request will be left hanging.
Interceptor
The interceptor can transform data between the controller and the client-side, which can perform functions for:
bind extra logic before / after method execution
transform the result returned from a function
transform the exception thrown from a function
extend the basic function behavior
completely override a function depending on specific conditions
(e.g., for caching purposes)
Filter
In Nest.js, the Filter generally refers to the Exception filter, which is responsible for processing all unhandled exceptions across an application:
a built-in global exception filter handles exceptions of type HttpException (and subclasses of it)
custom exception filters are designed for controlling the exact flow of control and the content of the response sent back to the client. For example, add logging or use a different JSON schema based on some dynamic factors.

Make sure nodejs express route can only be called once, until finished

My endpoint
POST example.com/user/transfer/
should not be able to be called by the same user until his earlier request has been processed. How do I do that?
Ideas
Keep a request Nonce in the user table (database) and make sure it can only be used once.
?
I might be not wrapping my head around it the right way.

Cannot request Iron Router server route twice without refreshing the client

I am calling a meteor method, which generates a file using fs. I wait for a callback giving me the path where the file exists, and then I request the file with a server route. The code is very similar to this SO answer. I have also tried using createReadStream (as demonstrated here) instead of passing the file directly to response.write.
This all works well on the client's first click of my export/download button. However, if for some reason they want to click the button more than once, the file will get generated but the file will not get served by Iron Router. There are no errors on the client or server. If the user refreshes the client, then the feature will work again (once).
Why do I need to refresh the browser in order to request the same server route a second time? Am I doing something wrong?
Example Application
Does the URL change when they click the first download? If so, and the second route is the same, you will not get redirected as you are already there. If this is the case, can you use the router hooks to send the user back to the route they came from?

Middleware to handle callback hell expressjs

Yesterday I came into a situation where in one "action" I need to do 2 db lookups and an insert.
The user submits data through a post, and I need to validate the token,validate another id and then insert the data he sent me.
At first I thought about using async, but I didn't find it as elegant as I would like it to be.
So I dag deeper in the expressjs and saw you can define middleware for specific routes.
So what if I created a middleware just for this route that handles the validation of the token and that other id? and the only thing that the action does is to actually insert the data?
Is that a good solution?

How is the default item controller registered/invoked in Orchard CMS?

I'm trying to get my head around how multi-tenancy and routing works in Orchard CMS.
As I understand when Orchard starts a new shell (tenant) all the active modules for that tenant are loaded and any modules that implement IRouteProvider "publish" their routes. A ShellRoute is then added for each route which will only be matched for requests made to that tenant's hostname/suffix.
The request is then handled in the normal way by MVC (looking in RouteTable.Routes for a match).
What I can't figure out is how the default ItemController is invoked since I couldn't find a default route for this in the source. Also I notice when browsing to the home page, the id route parameter is populated with that of the home page content item so I'm assuming there is some kind of pre-processing going on before the controller is hit?
There is a default IRouteProvider - Orchard.Mvc.Routes.StandardExtensionRouteProvider. It's responsible for registering default routes to controllers in form {module}/{controller}/{action}/{id}.
And yes, you're right - there is some preprocessing going on. A brief explanation:
Each item permalink (we call it an alias) is mapped to a route
that points to an action responsible for displaying it. By default -
Contents/Item/Display/{id}. Those mappings are kept in the database (AliasRecord and ActionRecord).
There is a special Route implementation - AliasRoute. This route is then registered once for each module and handles requests that match existing aliases. It all happens in Orchard.Alias module.
If the incoming request matches any alias, the call to AliasRoute.GetRouteData returns the underlying mapping. This way ASP.NET MVC framework knows which action to call.

Resources