Click here to Skip to main content
15,115,119 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Design architecture of a web application in Angular and Web API 2.0,web API is also divided in 2 layers data and business. I want to understand, where to place file upload code in business or data layer as per good architecture guideline.

What I have tried:

The Problem here is to make code thread safe, I want to save invoice information in database and invoice generation (invoice file creation) under begin and commit transaction, but at the same time I want to understand whether it is a good approach or not.
Updated 27-May-19 21:39pm

1 solution

Why is it a problem to make it thread safe? Typically a call is processed by a single thread (the old way), or a single async call "chain" that will also protect your code against thread issues - unless you start threads on your own.

But as you want to generate a file, I don't see where upload takes place?

The data layer only stores and access data. It will not have functionality to generate files etc. So that would mean the business layer will have to do it

In a high scale requirement environment, the invoice file creation would probably be in a background worker running of a queue. On small systems you can get away with generating it as the data is inserted in the database. If you have to ask this question you should not be working on a high scale system before you get a bit more experience.

For most small systems you can get away with one of these approaches:

Generate the file as the data is stored in the system.

1) Start transaction scope
2) Insert the data for the invoice
3) Generate the invoice file (and store it as well - database? file system, blob storage, …)
4) Commit the transaction. This way you will get a rollback and the invoice data will not be stored even if storing file on disk fails unless you are really unlucky (and you can be really unlucky with transactions as well, so don't worry about it)

Or alternative you can generate the file on read (if this is acceptable is more of a business question than a programming question). This way it is not stored in the database itself, and is typically only cached on the file system for a short while - if cached at all.
1) Start a database transaction
2) Store the invoice data
3) Commit the transaction

When the API request comes in, generate the file and return it. If performance show a problem and you often get multiple requests for the same file, then cache the generated files on disk. Just remember you must still check security - don't just return the file to the first the best caller knowing the invoice number (people will try adding or subtracting an invoice number from there own URL retrieving the invoice).
Navneet Kumar 9-Jun-19 2:35am
Thanks for detailed solution. I want to understand where to put my file saving code, at data layer or business layer, because it is not advisable to use the transaction scope in business layer.
lmoelleb 9-Jun-19 4:53am
In a lot of cases it is not advisable to use a transaction scope anywhere :). Where the correct level is for your application is impossible to say - you do not have the experience to determine it, we do not have enough insight into your application to determine it. So the best approach is to implement it in the least complicated way, then be ready to change it if needed. The last option I give (generate invoices on read) or the comment I made about high scale systems using a background queue both could satisfy the requirement of not needing transactions in the business layer. Saving the invoice data can be handled by a single transaction in the data layer. Generating an invoice in the data layer in order to avoid transactions in the business logic is not an option, as you would just move business logic into your data layer - meaning you would still have transactions in your business logic AND you would have business logic code in your data layer code. Worst of both worlds.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900