Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Web API 2 return OK response but continue processing in the background

I have create an mvc web api 2 webhook for shopify:

public class ShopifyController : ApiController
{
    // PUT: api/Afilliate/SaveOrder
    [ResponseType(typeof(string))]
    public IHttpActionResult WebHook(ShopifyOrder order)
    {
        // need to return 202 response otherwise webhook is deleted
        return Ok(ProcessOrder(order));
    }
}

Where ProcessOrder loops through the order and saves the details to our internal database.

However if the process takes too long then the webhook calls the api again as it thinks it has failed. Is there any way to return the ok response first but then do the processing after?

Kind of like when you return a redirect in an mvc controller and have the option of continuing with processing the rest of the action after the redirect.

Please note that I will always need to return the ok response as Shopify in all it's wisdom has decided to delete the webhook if it fails 19 times (and processing too long is counted as a failure)

like image 808
Pete Avatar asked Nov 21 '14 11:11

Pete


People also ask

Can we return views from Web API?

You can return one or the other, not both. Frankly, a WebAPI controller returns nothing but data, never a view page. A MVC controller returns view pages. Yes, your MVC code can be a consumer of a WebAPI, but not the other way around.

Can we have multiple post method in Web API?

Open your controller class, in our project its ValuesController. cs >> Copy paste below code, these are two sample post methods with a string input and return parameter – you can write your business logic in it. Similarly, you can add any number of POST, GET, PUT, DELETE methods in one controller.


2 Answers

There are a few options to accomplish this:

  1. Let a task runner like Hangfire or Quartz run the actual processing, where your web request just kicks off the task.
  2. Use queues, like RabbitMQ, to run the actual process, and the web request just adds a message to the queue... be careful this one is probably the best but can require some significant know-how to setup.
  3. Though maybe not exactly applicable to your specific situation as you are having another process wait for the request to return... but if you did not, you could use Javascript AJAX kick off the process in the background and maybe you can turn retry off on that request... still that keeps the request going in the background so maybe not exactly your cup of tea.
like image 57
Serj Sagan Avatar answered Sep 20 '22 00:09

Serj Sagan


I have managed to solve my problem by running the processing asynchronously by using Task:

    // PUT: api/Afilliate/SaveOrder
    public IHttpActionResult WebHook(ShopifyOrder order)
    {
        // this should process the order asynchronously
        var tasks = new[]
        {
            Task.Run(() => ProcessOrder(order))
        };

        // without the await here, this should be hit before the order processing is complete
        return Ok("ok");
    }
like image 14
Pete Avatar answered Sep 21 '22 00:09

Pete