Clarifying question about plumber's hooks: preroute, postroute, etc.

I've read about 30 references about plumber's API "plumbing" and I'm still not clear about, most specifically the "postroute" hook. Maybe I'm not thinking about this correctly but I'm trying to understand the sequence of what happens when a request comes in (a flowchart of any kind within the documentation would be unbelievably helpful). It feels like it would most useful if the logging of the response happened synchronously or after the response was sent to the user (to most efficiently limit any possibility of latency associated with the logging). I want to INSERT a row into a local postgres table, but I don't want to do it before returning the response and it appears as if postroute was created for this purpose, but none of the documentation makes this explicitly clear.

See plumber/R/plumber.R at 7b3e025dfa34196ad9d438474d310bb39b05db91 · rstudio/plumber · GitHub

Stages happens in the following order

  1. Request is received (preroute)
  2. plumber attempt to find a matching endpoint to process the request (route)
  3. plumber found a matching endpoint and processed the request (postroute)
  4. Serialize stage : steps to format the response to the client according to spec (pre, serialize, and post)

So it basically just execute functions in order and return a list in the form that httpuv can send back to the client. Something like below.

        status = 200L,
        headers = list('Content-Type' = 'text/html'),
        body = body

Hopefully, this clarifies this part. If there is a flowchart, I'm not aware of it. I'm a code monkey and visually challenged, but I would gladly support a flowchart addition if someone was to make one.

Now. The logging part.

The request context is lost at the end of the serve (parent call) execution. Logging will add some latency. You can minimize it by separating the creation of the log and the writing to the database.

In production, we pipe the log to stdout and capture stdout using another tool (stackdriver or the likes).

We have debug levels, most verbose logging introduce about 5ms latency for a 5mb log per call and production logs have < 1ms added latency for problems detection, load monitoring.

If you were thinking of doing a write to the database in the postroute stage, it is going to happens before returning the request to the client.

Depending on your application context, select the solution that best fits your needs. It might be R (plumber). Or it can be something else, fastapi... We sometimes mix RestRServe and plumber depending of the use case.

Have a great day.

Thank you for this extra detail. Super helpful.

From an intuitive POV, I’m a bit confused as to why there isn’t some way to push to a log after prioritizing the user’s response, but I’m very new to this, so I fully recognize that there are some obvious foundational details about APIs that I’m probably blind to.

Thanks again!

It's a bit like Russian dolls, the last step in the stack is to return the response to the client via httpuv and it switches back to waiting for the next request, there is nothing in between. As it is right now, logging at any point will incurs a latency hit, but it is relatively small relative to network latency. Logging is not very CPU intensive. Hopefully you are able to go on an R adventure from there