How to create an overload API or function in Actix-web?


I need to create a couple of endpoints for an API service project. These API can accept encrypted and un-encrypted one (for development). Both parameters then are passed into a same function. For example:

  1. /api/movie/get with encrypted parameter (for production)
  2. /dev/movie/get with un-encrypted parameter (for development)

Current implementation in actix_web

I use actix_web and routes (not macro) to provide path routing. Modified from the sample code below

use actix_web::{web, App, HttpServer, Responder};

async fn index() -> impl Responder {
    "Hello world!"

async fn main() -> std::io::Result<()> {
    HttpServer::new(|| {
            // prefixes all resources and routes attached to it...
                // this handles requests for `GET /app/index.html`
                .route("/index.html", web::get().to(index)),
    .bind(("", 8080))?

For each API endpoint, I had to create 2 functions, such as:

/// for encrypted one
/// PATH: /api/movie/get
pub async fn handle_get_movie(
    app_data: Data<AppState>,
    Json(payload): Json<EncryptedPayload>,
) -> Result<impl Responder, Error> {

    // decrypt the content
    // this is the only difference between un-encrypted and encrypted endpoint
    let params = payload
        .map_err(|_| MainError::Malformatted)?;

    // other codes here....

    Ok(Json(ReplyInf {ok: true}))
/// for un-encrypted one 
/// PATH: /dev/movie/get
pub async fn handle_get_movie(
    app_data: Data<AppState>,
    Json(payload): Json<UnencryptedPayload>,
) -> Result<impl Responder, Error> {

    // other codes here. These codes are exactly identical with the above function...

    Ok(Json(ReplyInf {ok: true}))


Since both functions are similar, does it possible to combine them both into a single function ? a function "overload" maybe ?

The problem is this line Json(payload): Json<UnencryptedPayload> in the parameter function. I tried to use generics like Json<T>. this doesn't work.

I can use the environment variable to control which should be active (EncryptedPayload or UnencryptedPayload). I can use one path for each endpoint (eg: /api/movie/get) and don't have to write the same functionality twice.

Because parameter injection is type-based, not without abstracting over UnencryptedPayload and EncryptedPayload.
But that could possibly be as simple as

enum Payload {

And updating the fn parameter from Json<UnencryptedPayload> to Json<Payload>.
Just add any appropriate trait impls / attribute macros.

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.