|
Hello !
I have a question about what the best approach/design pattern could be to achieve communication between two or more MVC API's on the same machine.
Currently I have a single Web API delivering data to my web site. For reasons too long to explain here, we are refactoring the API to split it in multiple modules. One being the main API with the core information (think : Order database with detailed info), and the satellite API's having lists of orders, but without their details.
Of course, when a satellite API gets a request, it could just reply with the list of orders (which it knows of), but I want it to reply with the details of each orders ..
Important to mention is that all data is in memory, no database is behind the whole thing (otherwise it would be trivial).
Knowing that all API's would be on the same server, and that I obviously want to avoid ping-pong between the client site and the API's .. I would like to have my satellite API ask my main API about this information.
I have looked into WCF services, but I am not sure if that's the appropriate solution, and also about how to integrate it in my existing projects. I do already have the multiple API's running (not in prod) as normal ASP .Net MVC projects.
In an ideal world, I would simply "expose" a few methods from the main API, so that the other ones can call it. I've also looked at the other ways to do IPC, but I am unsure which would be best in my case.
Side questions about WCF Services:
- do they have to be a project of their own ? or could I say that a few methods in my API are the actual service ?
- What about the service reference that the client has to know of ? how do I specify where the service actually runs ? This is not necessarily known during dev, what if the server is hosted elsewhere ?
- Do I have to care about async calls here ?
Note: I'm obviously new to WCF, be kind
Thanks a lot
Fred
|
|
|
|
|
As you have tried to keep the question compact, the one-liner answer to this would be to use Microservices architecture and use each individual module as a separate service; read here .NET Microservices. Architecture for Containerized .NET Applications | Microsoft Docs
Quote: I have a single Web API delivering data to my web site. I can see a microservice here.
Quote: when a satellite API gets a request, Another microservice here.
Quote: Important to mention is that all data is in memory, no database is behind the whole thing (otherwise it would be trivial). Another microservice here, that manages the data for the entire system—keeping the data aside and giving it some high-availability, as if this service goes down, entire cluster is down. This is the point that you need to discuss with your team again. Quote: I would like to have my satellite API ask my main API about this information. Exactly the core benefit of microservice architecture, your clients would only need to know the website. Internal communication and services would be abstracted away from them.
Quote: I have looked into WCF services, WCF is quite old and doesn't quite fit the modern demands of the solutions. If, for instance, you would want to go to cloud hosting solutions, then microservices and their modern approach to communication is much more scalable and feasible. WCF although supports various protocols, sometimes that extra optionality is a downside. Trust me with this—or not.
Quote: I would simply "expose" a few methods from the main API, so that the other ones can call it. I've also looked at the other ways to do IPC, but I am unsure which would be best in my case. Since, ASP.NET Web API is based on REST, talk about REST mostly and in REST you can use services like OpenAPI (Swagger) and generate a documentation for the users that they can access.
About Swagger Specification | Documentation | Swagger | Swagger
Now coming to the last part of your question,
Quote: do they have to be a project of their own ? or could I say that a few methods in my API are the actual service ? You can decide, a single project might have more complex structure and developmental issues. Separate projects would be simpler to manage. This is for WCF and ASP.NET etc. For microservices, you should try to keep everything separate. You can even use different languages and runtimes.
Quote: What about the service reference that the client has to know of ? how do I specify where the service actually runs ? This is not necessarily known during dev, what if the server is hosted elsewhere ? You should consider using DNS for that. Most services are to be managed by the hosting providers, they allow you to control that. Your API definition will grant enough information to the users that they can manage it from there.
Quote: Do I have to care about async calls here ?
Yes, if you want to have a scalable solution, then yes. A friend of mine (along with me) worked on a course that speaks about the same thing, Asynchronous Programming in .NET Core [Video]
I hope this answers your questions.
The sh*t I complain about
It's like there ain't a cloud in the sky and it's raining out - Eminem
~! Firewall !~
|
|
|
|
|
Thanks !
I will dig deeper into the micro-services architecture, in fact, it's a bit my goal with each API.
Good to know that WCF can be left out of the picture.. it was kind of everywhere when I googled looking for alternatives :s
Fred
|
|
|
|
|
Yeah, I've played this game before, and while it's nice to think that everything is in memory and so it should be easy, there are some surprising hurdles that need to be cleared first. Here are some of my IPC notes.
The most important initial concern that you need to address is: what is the exact nature of the communications that need to occur between the services? Is the communication simplex or do we need duplex? What sort of update rate can we expect to see? Do we need to acknowledge connection (like TCP) or can we fire-and-forget (like UDP)? Will you only ever have 2 communicating modules, or might you want to add more down the line?
Defining the nature of the interactions will help you determine the appropriate technology to use. In the most basic model: one application writes data that can be read by another application, the easiest thing in the world is to have it write to a file that the other app(s) will read. This is a good, stable solution that works well in situations where race conditions are low-impact issues.
If you need duplex communications, things become slightly more complicated. For most purposes, a LocalDB instance can be used to share data between applications. This can work very well for bi-directional communication between applications, but, like the file method, it does not work for event-based interactions: it just shares flat data.
If the two processes need to talk, i.e. one needs to actively query the other, the level of complexity jumps considerably. You can query the other over the NIC using the standard WebAPI format and HttpClients, and that's likely to be your easiest solution. I know it sounds stupid, but having walked this path before, unless you're willing to spend some time architecting an IPC process, it is the easiest route. Another option is to have your process actively watch directories for changes and use the file approach, but there is a serious performance cost to implementing this solution.
The other option is to make use of an Inter-Process Communication (IPC) technology. In .NET that generally means using Pipes or Memory-Mapped Files. Both have benefits and pitfalls, but are best suited to event-driven processes and the communication of complex data.
Memory-Mapped files are the closest thing to what you're initially talking about. It's a section of memory that can be shared between multiple processes that has certain thread safety mechanisms that attempt to address concurrency problems. I can tell you from the start, there are complexities to using these that will surprise you, and I've not had enough success with these to advise you more about them.
Pipes are the IPC processor that I do know a bit more about, and they come in 2 flavors: named and anonymous. Named pipes provide a great mechanism for multiple processes to hook into a central bus and talk to one another. They're a good way to have an extensible system that future modules can hook into. Using them appropriately requires you to do a couple of things: first you must secure them appropriately because they are available via RPC over the network, and second is to develop an addressing and message-passing scheme for your modules.
Anonymous pipes are unidirectional (though 2 anon pipes used in conjucntion can provide full duplex communications) and work well when you have a pre-defined number of modules. The work in this case is moved from developing addressing/messaging over to initial establishment of the pipe.
There are other approaches, many encapsulated by WCF in fact, that are generally touched on here:
Interprocess Communications - Windows applications | Microsoft Docs
Anyway, have fun dipping into the joy that is IPC!
"Never attribute to malice that which can be explained by stupidity."
- Hanlon's Razor
|
|
|
|
|
The end game looks something like this:
- One main API
- Several smaller API's, mostly independant, but occasionally requiring to get data from the main API's in-memory repository.
If I had had the liberty to do it, I would have used Redis or something similar instead of having one in-memory repo for each API, but it's not a possibility due to company standards etc.. That would have been easy .. because aside from sharing some data, my API's don't really need to communicate.
Nathan Minier wrote: what is the exact nature of the communications that need to occur between the services? Smaller API's would just request info, and the main API would reply, never the other way around.
Nathan Minier wrote: Is the communication simplex or do we need duplex? Simplex. Only from the smaller API's to the main API, never the other way around (otherwise I'd have seriously screwed up my architecture..).
Nathan Minier wrote: What sort of update rate can we expect to see? The actual update of the data in the memory of the main API is not an issue, I already have a flip-flop mechanism that prevents delivering data while it is being updated. So basically anyone asking data is only getting it from the "active" part of the memory, while the "inactive" is being updated. Thus the smaller API's would also query from the "active" part. And I'm not managing TB's of data either
Nathan Minier wrote: Do we need to acknowledge connection (like TCP) or can we fire-and-forget (like UDP)? Fire & forget could do (it's on the same server) as long as I can ensure that there is no data loss (which screams more TCP than UDP anyway :s)
Nathan Minier wrote: Will you only ever have 2 communicating modules, or might you want to add more down the line?
One main, multiple "clients". They're not truly clients because all API's would be autonomous and managing their own set of data, but the whole thing is related, and in time, we will want to cover more business areas, so we will definitely have more "clients".
|
|
|
|
|
Hi All,
I am little (a lot in fact) hazy on ASP.NET authentication methods...
At any rate I am trying to diagnose the following problem on an existing web app that use OpenID to query our ADFS server to authenticate users.
We followed that process:
https://docs.microsoft.com/en-us/windows-server/identity/ad-fs/operations/configuring-alternate-login-id
And the AlternateLoginID is a custom LDAP attribute (namely interactUsername )
With some custom C# code I created a an AD user with the following properties:
UPNLogon: IU-3762@licensys.com
SAMAccountName: dev\IU-3762
interactUsername: llandersxA
when I try to login with llandersxA on the ADFS login page, it tells me:
Incorrect user ID or password. Type the correct user ID and password, and try again.
And replace the user name I entered (llandersxA ) with dev\llandersxA before trying again (which is not recognised either)
Any idea on what I might be missing? or link that could help on that topic?
Cheers!
[EDIT] the plot thickens!
If the interactUsername looks like an email, say llanderxA@foo.bar it works!
modified 4-Mar-19 22:33pm.
|
|
|
|
|
Please note I have very limited knowledge of MVC. I have found helpful articles using MVC on this topic, but am having trouble distinguishing MVC vs Core differences. For example, I found a great answer in this forum but I don't quite understand the controller portion.
I'm wanting to bind a dropdown list to a database table.
I have a Costcenters model (and in my context file I have "public virtual DbSet<costcenters> Costcenters { get; set; }"):
public partial class Costcenters
{
public int Id { get; set; }
public string CostcntrNo { get; set; }
public string CostcntrName { get; set; }
public string CostcntrMngr { get; set; }
}
I'd like to add the dropdown to my Register.cshtml page, submitting the Id but listing the CostcntrNo in the dropdown:
<select asp-for="Input.CostcntrId" class="form-control" asp-items="@(new SelectList(Model.Costcenters,"Id","CostcntrNo"))">
<option disabled selected style="display:none">--select an option--</option>
</select>
Here's the part I believe I'm messing up on. All I've added to Register.cshtml.cs so far for this is (shortened for the question):
public List<Costcenters> Costcenters { get; set; }
[BindProperty]
public InputModel Input { get; set; }
public class InputModel
{
[Required]
public int CostcntrId { get; set; }
}
public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
if (ModelState.IsValid)
{
var user = new ApplicationUser
{
CostcntrId = Input.CostcntrId
}
}
Would the easiest way to complete this be to add a "LINQ query" in here?
Currently when I run this in development, I receive the "Value cannot be null" error. I may be closer than I think, but I have a poor understanding of this method so any explanation is greatly appreciated.
|
|
|
|
|
I think part of the problem is that you seem to be using Razor Pages[^], which is subtly different from MVC (either Core or MVC5).
Microsoft have a decent tutorial which covers using drop-down lists in Razor Pages:
Razor Pages with EF Core in ASP.NET Core - Update Related Data - 7 of 8 | Microsoft Docs[^]
Basically, you need to populate the list of cost centres in both the OnGetAsync and OnPostAsync methods.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Yes, this is the tutorial I was searching for. Thank you sir!
|
|
|
|
|
Is it enough for methods to be capture and report JavaScript errors on web applications on computer and mobile devices?
window.onerror = function (msg, url, lineNo, columnNo, error) {
return true;
};
|
|
|
|
|
Just starting with an ASP.Net Core project and my first instinct is to separate the web api project and the UI project because that is the way all desktop apps should be written.
Does that apply for web apps. The API will also be accessed from a mobile app, will that make a difference.
Never underestimate the power of human stupidity -
RAH
I'm old. I know stuff - JSOP
|
|
|
|
|
Yes, you can do it.
You could create an asp.net core API and then, for example, a UI application in Angular or React.
In Visual Studio 2017 there is a template that you could create the API and de UI together too.
|
|
|
|
|
The question was not whether I can do it but whether i should do it. I should have posted this in the design forum
Never underestimate the power of human stupidity -
RAH
I'm old. I know stuff - JSOP
|
|
|
|
|
Sorry man, my bad.
But I prefer to build the API in a separate project and then the UI, mainly if others will need to access the API like a mobile app.
|
|
|
|
|
Yet every example I see has the UI and the API in a single project. I wonder if it makes a difference if the mobile app references the single app (including the UI components) or an API only app.
Never underestimate the power of human stupidity -
RAH
I'm old. I know stuff - JSOP
|
|
|
|
|
I think the examples that commonly exist on the web are made in a single project for simplification. But there is no difference for a mobile app to references a blended project or only the API.
In my opinion, if possible, creating the UI separate from the API gives me more flexibility, for example, to develop another UI to update the previous.
|
|
|
|
|
Good day. I would like to create a simple API using C#.Net that read Oracle Database. Where must I start?
|
|
|
|
|
sellol wrote: Where must I start? At the beginning.
But seriously, what do you expect your API to do or, what features will it provide? The most likely starting point is probably to work on the basic design, and decide how many of the Oracle features you want to expose.
|
|
|
|
|
Hi. I want to create just a simple CRUD. Just want to create endpoints. Like myserver.com/v1/employees/all,
myserver.com/v1/employee/id/{1}
Etc
|
|
|
|
|
Sorry neither your original question nor this make any real sense. These forums are for technical questions, so you need to be much more specific. We cannot guess what your design requirements are. And the above URL is not valid; no idea what myserver.com is supposed to lead to.
|
|
|
|
|
Hi. Are you going to help me with creating basic API reading from Oracle?. If you cant please refer me to a specific link.
|
|
|
|
|
|
I'll be a little more specific than Richard - Google[^]
Only because he managed to get more detail out of you. API means you want to expose the capabilities of Oracle, CRUD is a solved problem!
Never underestimate the power of human stupidity -
RAH
I'm old. I know stuff - JSOP
|
|
|
|
|
sellol wrote: Where must I start?
Part 1
1. Learn basics of C#
2. Learn basics of accessing Oracle from C#
3. Create test application that includes both of the above.
Part 2
1. Learn basics of "web' process
2. Create code that provides basic UI screen.
3. Create test application that includes both of the above.
Part 3
1. Learn how a web application interacts with a server application
2. Optional: At least read up a bit on security (how to do a user login.)
Part 4
1. Decide on a minimal table to which you can create, update, query and delete entries.
2. Create a UI that allows you to do 1
3. Create a server side code that allows 2 to interact with it and that does the database actions.
Part 5
1. Put all of the above together to create your application.
|
|
|
|
|
Thank you very much man. You are a true leader.
|
|
|
|
|