Hi Team,
I am trying to create a microservice-based application. However, when I create the services as microservices, I notice that each microservice contains only the following layers:
API Contracts Tests
I would like to structure each microservice using a layered architecture similar to:
Domain Application EntityFrameworkCore API Contracts Tests
Could you please advise how I can achieve this architecture when creating microservices?
I would appreciate a support call as soon as possible, as this is currently blocking my progress.
Thank you.
2 Answer(s)
-
0
- In ABP’s Microservice startup template, each “service” is intentionally kept minimal (typically HttpApi + Application.Contracts + tests) because ABP expects you to put the actual business layers (Domain/Application/EFCore, etc.) into separate modules/bounded contexts that can be deployed as microservices or plugged into a monolith. In other words: in ABP microservices, the layered architecture is achieved via modules, not by forcing every microservice host to contain every layer project.
- To get a per-service layered structure like
Domain / Application / EntityFrameworkCore / HttpApi / Application.Contracts / tests, you should create each microservice as an ABP module solution (microservice-first module design) and then host it with a small HttpApi.Host (or similar) project.- Practical approach:
- Create a new module solution for your bounded context/service (this module will contain the layers you want: Domain, Domain.Shared, Application, Application.Contracts, EntityFrameworkCore, HttpApi, etc.).
- Create (or keep) a thin service host project (your microservice’s running API) that references that module’s
*.HttpApi(and usually*.EntityFrameworkCore) and configures the database connection / migrations. - Deploy that host as the microservice.
- Practical approach:
- If you want a real working reference showing how ABP microservices are organized, use eShopOnAbp as a guide and model your bounded contexts similarly (each bounded context is effectively a module with its own layers; the “service host” stays thin).
For the requested support call: ABP/Volosoft scheduling and non-technical/support logistics are handled via the contact channel:
- https://abp.io/contact
Links you can follow for the official guidance and an example:
- https://abp.io/docs/latest/framework/architecture/microservices/
- https://abp.io/docs/10.4/framework/architecture/microservices/
- https://abp.io/community/articles/9k1yvrp6
- https://github.com/abpframework/eShopOnAbp
This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.
Markdown supported.Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post) -
0
Hi,
The 3-project layout you see (
HttpApihost +Contracts+Tests) is by design — the microservice template usesservice_nolayersso each service stays small. The reasoning is here: https://abp.io/docs/latest/solution-templates/microservice/microservices#solution-structure-of-microservicesYou can absolutely layer a microservice the same way ABP's built-in modules (
Volo.Abp.PermissionManagement,Volo.Abp.Identity, etc.) are layered. For a microservice on EF Core you end up with these projects in the service folder:*.Domain.Shared *.Domain *.Contracts ← acts as Application.Contracts in the microservice template *.Application *.HttpApi *.HttpApi.Client *.Web ← Razor Pages + menu + static resources (modular UI) *.EntityFrameworkCore * ← service host (the "API") *.TestsI built a working reference solution end-to-end (
ProductServicelayered into all of the above, called through the Web Gateway, also consumed from a Razor Page via the dynamicIProductAppServiceproxy). Drop me an email at liming.ma@volosoft.com and I'll share the zip — use it as a template for the service folder layout.Adding a new layered microservice to your solution
ABP Studio →
Add→New Module→Microservice, keep Enable integration checked. The wizard wires the new service into the AuthServer, Web Gateway, Identity'sOpenIddictDataSeeder, theappsettings.jsonfiles, Helm charts, and the Solution Runner profile for you.In the generated service folder, add the layer projects (
*.Domain.Shared,*.Domain,*.Application,*.HttpApi,*.HttpApi.Client,*.EntityFrameworkCore, and*.Webif the service has UI). Copy the csproj +*Module.csfrom the corresponding folders in the reference zip, then rename namespaces to match your solution.Wire the host (the service "API"):
- Add
ProjectReferenceto the new layer projects in the host csproj. - Add the new layer modules to the host module's
[DependsOn(...)]. - In the host
*DbContext, addDbSet<YourEntity>and call theConfigureYourService()extension method (defined in*.EntityFrameworkCore) insideOnModelCreating. - Remove the host's original
ConfigureAutoControllers()— it moves into the*.HttpApimodule.
- Add
EF Core migration:
dotnet ef migrations add Added_YourEntityanddotnet ef database update.To show a page for it in the web app:
Reference the new
*.Webproject and add[DependsOn(typeof(YourServiceWebModule))]to the web module — the page and menu show up automatically.Add a per-service entry to the web app's
appsettings.jsonRemoteServices:"RemoteServices": { "Default": { "BaseUrl": "http://localhost:<webgateway>" }, "YourService": { "BaseUrl": "http://localhost:<your-service>" } }The per-service entry is required because the dynamic proxy queries
<BaseUrl>/api/abp/api-definitionto discover endpoints, and the Web Gateway's default/api/abp/*route forwards to the Administration service, so it never returns your service's methods. Pointing the proxy at the service directly is the standard pattern.
FAQ
Can I keep the simpler 3-project layout for some services and use the layered one for others? Yes — they coexist in the same solution. Reserve the layered structure for services with real business logic.
Do existing baseline services (Identity, Administration) need to be re-layered? No. They're already wired and tested. Layer only your own business services.
If anything doesn't work out while you're wiring this up, just reply here and I'll have a look. Sharing your project is the fastest way for us to debug — push it to a private GitHub repo and invite https://github.com/maliming.
Thanks
Markdown supported.Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)