Middleware

The actix-web crate supports middleware that can be attached to an App instance to process every request and response. Middleware helps to log requests, transform them, or even control access to a group of paths using regular expressions. Consider middleware as handlers for all incoming requests and outgoing responses. To create the middleware, we first have to implement the Middleware trait for it. Look at the following code:

pub struct Counter;

impl Middleware<State> for Counter {
fn start(&self, req: &HttpRequest<State>) -> Result<Started> {
let value = *req.state().0.borrow();
*req.state().0.borrow_mut() = value + 1;
Ok(Started::Done)
}

fn response(&self, _req: &HttpRequest<State>, resp: HttpResponse) -> Result<Response> {
Ok(Response::Done(resp))
}

fn finish(&self, _req: &HttpRequest<State>, _resp: &HttpResponse) -> Finished {
Finished::Done
}
}

We declare an empty Counter struct and implement the Middleware trait for it.

The Middleware trait has a type parameter with a state. Since we want to use the counter of our State struct, we set it as a type parameter, but if you want to create middleware that is compatible with different states, you need to add type parameters to your implementation and add an implementation of necessary traits that you can export to your module or crate.

The Middleware trait contains three methods. We implemented all of them:

  • start is called when the request is ready and will be sent to a handler
  • response is called after the handler returns a response
  • finish is called when data has been sent to a client

We use the default implementation for the response and finish methods.

For the first method, we return a response without any changes in the Response::Done wrapper. Response also has a variant, Future, if you want to return a Future that generates an HttpResponse.

For the second method, we return a Done variant of the Finished enum. It also has a Future variant that can contain a boxed Future object, which will be run after the finish method ends. Let's explore how the start method works in our implementation.

In the start method implementation of the Counter middleware, we will count all incoming requests. To do this, we get the current counter value from RefCell, add 1, and replace the cell with a new value. At the end, the method returns a Started::Done value to notify you that the current request will be reused in the next handler/middleware of the processing chain. The Started enum also has variants:

  • Response should be used if you want to return a response immediately
  • Future should be used if you want to run a Future that will return a response

Now, the microservice is ready to build and run.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.224.68.28