Web API - Handling the long running call when aggregating the calls - asp.net-web-api

I have a web api project which works as a GateWay for other Mobile clients. When the mobile client makes a call to this Gateway it internally calls the existing services which are hosted by another project and it aggregates the results and return to the client. I have recently come across a situation when my gateway is internally making 3 calls first 2 are returning the data fast but the 3rd call is taking lot of time I want to know the best way to handle this scenario.

Ensure that the return type of API action methods is async Task<YourModelDataType>.
For example, let's say you have a HomeController controller as follows:
public class HomeController : ApiController
{
public async Task<YourModelDataType> Index()
{
return new YourModelDataType()
{
Property1 = await ApiService1.GetData(),
Property2 = await ApiService2.GetData(),
Property3 = await ApiService3.GetData(),
};
}
}
Ensure that calls to the other API projects are awaited. This improves scalability on the server side. i.e. server resources are free to serve other requests while awaiting response from other API services.

Related

How Api gateway combine responses form microservices

According to article https://dzone.com/articles/building-microservices-using there is a statement:
The API Gateway is responsible for request routing, composition, and protocol translation. All requests from clients first go through the API Gateway. It then routes requests to the appropriate microservice. The API Gateway will often handle a request by invoking multiple microservices and aggregating the results.
I'm wondering, based on Zuul example, how the API Gateway achiving this?
Let's imagine we have a 2 microservices, one which retrives all available product names and second one which returns descriptions of products. In monolithic architecture we would have only one request to get all needed data. In microservice architecture API gateway should combine responses (from both microservices) and return one response.
How this funcionality should be implemented? Are there any guidelines or articles on that?
Not all API gateway supports aggregation. This is an example of aggregating response of two service for a single client call using nginx.
The side effect of this being it introduces coupling at the API gateway layer.
Another possible solution is to use aggregation microservice. The main responsibility of this service is to provide a client side api. It can make multiple calls to other microservices to formulate the response for the client.See sample below
#RequestMapping(path = "/product", method = RequestMethod.GET)
public Product getProduct() {
var product = new Product();
String productTitle = informationClient.getProductTitle();
Integer productInventory = inventoryClient.getProductInventories();
if (productTitle != null) {
product.setTitle(productTitle);
} else {
product.setTitle("Error: Fetching Product Title Failed"); //Fallback to error message
}
if (productInventory != null) {
product.setProductInventories(productInventory);
} else {
product.setProductInventories(-1); //Fallback to default error inventory
}
return product;
}
Full example here

Update clients in asp.net core 2.0 using SignalR

I am going through several examples on Asp.net Core WebAPI with SignalR where most of them are demonstrating simple chat application where this is what Hub returns:
return Clients.All.InvokeAsync("Send", message);
And this is how it gets called in Startup.cs
routes.MapHub<Chat>("chat");
The above example is good if message is not be send and updated to all the clients. In my case I have several APIs to be called whenever a data is changed:
Like Bank Transaction is done, I have to update ledger and several other reports at client side. But I don't see any option to pass Json.
Not finding exactly how to do this so that WebAPI gets refreshed everytime a change is there in the database.
As far as I understood, here "chat" is the endpoint which will be called from the frontend.
In this case what will happen to the endpoint I have created so far. Have a look at the below code example:
This api is to be called every time an entry is done:
public async Task<object> GetMarket(string marketshortcode)
{
Markets market = new Markets(marketshortcode);
return market.GetMarket();
}
and this the entry:
[Authorize]
[HttpPost]
public async Task<object> sellCurUser([FromBody] SellCur model)
{
if (model != null)
{
SellCurUser suser = new SellCurUser();
suser.sellcur = model;
my addition code...
}
return ....
}
There are several more endpoints which needs to be called at certain update/creation.
Now the point is how these apis will be changed or even not changed at all.
Do anyone have any example to understand it simply.

Web API 2 - Unity IOC - Shared instance per request variable

I am using web api with unity IOC.
web api client passes client-id in request header and based on this value dependencies are resolved to create a external dll's method instance.
creation of this instance take around 6-7 seconds which is creating performance issues in web api.
What I want is to prevent instance creation for call with same client-id in header.
This is how I have implemented till now:-
//========================== ArchiveFactory ==========================
ArchiveFactory archiverFactory = (HttpRequest httpRequest) =>
{
container.RegisterType<IArchive, Archive>("Archive",
new HierarchicalLifetimeManager(),
new InjectionConstructor(
new ResolvedParameter<IStoreClient>(),
Helper.GetArchiveContext(httpRequest))
);
return container.Resolve<IArchive>("Archive");
};
container.RegisterInstance(archiverFactory);
To be specific in my requirement - I am calling amazon services to retrieve images and there is a corporate dll which invokes amazon.
You can use caching mechanism at the controller/API layer(e.g Strathweb.CacheOutput.WebApi2) and you can decorate the controller method like this below. It's can cache based on parameter so if request comes in with same parameter, it will return results from cache.
[HttpGet]
[Route("")]
[CacheOutput(ServerTimeSpan = 60, ExcludeQueryStringFromCacheKey = true)]
public IHttpActionResult GetProducts(string clientId)
{
var product = new List<Product>();
return Ok(product);
}
Also, you might want to check the class constructor that you are trying to instantiate for issues that is taking it too slow. You may want to consider using lazy loading too if that will apply.

How to delay the response of my Web API

I am working on a Web API project and that has an Artist Web API Controller. On there, there is the api/artist method that is a GET for all artists.
When making the call to this method, I would like a 3 second delay before I serve the data, how can I achieve this?
CODE
public class ArtistController : ApiController
{
private GlContext db = new GlContext();
// GET api/Artist
public IQueryable<Artist> GetArtists()
{
return db.Artists;
}
}
I know that you wouldn't want to do this in a production environment, but I am playing with preloaders, and in order to test them properly I need to introduce this delay.
If it is just for testing you can always go for Thread.Sleep(3000)
http://msdn.microsoft.com/en-us/library/d00bd51t%28v=vs.110%29.aspx

Increasing Timeout Values in ASP.NET MVC 3

I have a JSON service that I'm exposing via ASP.NET MVC 3. This service is exposed as an Action on a Controller. I can successfully call the action. However, occasionally, the action takes too long to complete. Because of that, my caller fails due to a timeout. My question is, how do I change the timeout threshold's in ASP.NET MVC 3.
If you need do some task that you know can take a little while would be nice use AsyncControllers, and you can set diferent timeout betwen actions
for example
[AsyncTimeout(3000)] //timeout in miliseconds
public void DoTaskAsync(){
//something that takes a long time
AsyncManager.Parameters["result"] = contentresult; //Contentresult is your data result of process
}
public ActionResult DoTaskCompleted(String result){
return json(result);
}
http://msdn.microsoft.com/en-us/library/ee728598.aspx#Y4400 for details...
otherwise... HttpContext.Server.ScriptTimeout = 3000;
It depends what is timing out. If it's just the server response, I believe you can set it in the controller itself (in seconds):
HttpContext.Server.ScriptTimeout = XXX;
If it's something like the session or authentication timing out you will need to extend those values.

Resources