Introduction To ASP.NET Backend Development From Scratch
Introduction
Understanding what happens under the hood and rebuilding the wheel is my favorite way to learn. However, when starting backend development with .NET, I find that the courses do not help. All of them make you memorize some code and rewrite it, and congratulations, you have a CRUD app and you become a developer!
So in this series of tutorials, I will try to help you approach backend development from the ground up, remaking some of the important parts of the ASP.NET framework. Well, you have to know that these tutorials are not close to being enough. I’ll draw an approximate path for you, and you will take care of the details.
Note also that this is a practical tutorial. I will share the code with you, but you need to be able to build it by yourself first.
What is an API?
API is a very interesting concept. It is a web-specific concept. Web APIs are only one type of it. An Application Programming Interface is a way for two programs to communicate. For example, if you have ever created a console application, you have already used an API because the console is not a part of your problem but an independent software that you are using to handle the inputs and outputs for you.
C# has implemented the code that interacts with the console API for you, so let’s try to build our own simple API that runs on the same machine (no web):
Build Calculator API
Well, calculations do not need an API because any programming language provides you with a math library. However, we will make this simple API for learning purposes.
The Calculator application is independent from the consumer application (that uses the calculation API), so how can they communicate? Try to think about it.
Well, a simple way that all of you can implement is communicating using a “file”. This may look weird, but it can get the job done.
The calculator application when running will continuously read data from a file. Let’s name it Request-File.txt. If the file is empty, it will do nothing. If there is content, it will read it. This data is a string representing the calculation operation we need to perform. The data comes from other applications that need to use our API. After calculating the result, we will send it to the application using another file. Let’s name it Response-File.txt. (Notice that for now we are only handling the case where we have only one application using the API and one request every time). It can be, for example, it may be simple like this:
ADD 15 4
or may be complicated like this :
Calc-API : Addition-OP ([num1]:{15} [num2]:{4})
You actualy can use any format you want, however you must create method that convert from string to a usable object, so I will use the most simple one, you can use what ever you want if it can make the job done,
So we need a class lets name it CalcOperation (name it as you want) and methods for converting and calculating the result, you can find the code here.
Note : i will use this simple format as an example : Op Num1 Num2
class CalcOperation
{
double leftOperand;
double rightOperand;
OperationType operationType;
// Received String must be on this formate : Op Num1 Num2
static public CalcOperation FromString(string operationAsString)
{
// ADD 32930.121 1231.01 (example)
var parts = operationAsString.Split(" ");
return new CalcOperation
{
leftOperand = double.Parse(parts[1]),
rightOperand = double.Parse(parts[2]),
operationType = parts[0] switch
{
"ADD" => OperationType.Add,
"SUB" => OperationType.Sub,
"MUL" => OperationType.Mul,
"DIV" => OperationType.Div
}
};
}
public decimal Calc()
{
return operationType switch
{
OperationType.Add => (decimal)(leftOperand + rightOperand),
OperationType.Sub => (decimal)(leftOperand - rightOperand),
OperationType.Mul => (decimal)(leftOperand * rightOperand),
OperationType.Div => rightOperand == 0 ? 0 : (decimal)(leftOperand / rightOperand),
};
}
private CalcOperation(){}
enum OperationType {Add=1, Sub=2, Mul=3, Div=4};
}
The CalcAPI code is here
This is great, this class can parse the request into object and perform the calculation and get the result , now lets use it now to parse the data from Request-File.txt and calculate the result :
class CalculatorAPI_V1
{
static string RequestFilePath = "PATH/Request-File.txt";
static string ResponseFilePath = "PATH/Response-File.txt";
public static void HandleOnCommandFromOneApplication()
{
while(true)
{
var lines = File.ReadAllLines(RequestFilePath);
if(lines.Length > 0)
{
var operationAsString = lines[0];
var calcOperation = CalcOperation.FromString(operationAsString);
decimal result = calcOperation.Calc();
File.AppendAllText(ResponseFilePath,"Result:" + result.ToString() + "\n");
File.WriteAllText(RequestFilePath,""); // Empty the request file
}
else
{
Thread.Sleep(1000); // Pause the application for 1 second
}
}
}
}
What we did is putting our program on Infinity loop where he will keep reading the file content, check if it has content so he get the first line, convert it to calcOperation, use the “Calc” Method to get the result, then write the result to the response file, with the prefix “Result:”, but you can write it as you want, we empty the request file (for now we will not handle the case of multiple requests or multiple application sending them) so the application using our API can receive the result from the response file.
Now, lets use our API from another application : let it be a console application lets name it CalcClient, the application ask the user to chose an operation and enter 2 numbers, and show the calculation result, however the app will not calculate the result but will request it from our CalcAPI
We can handle the user input like this :
OperationData GetUserInput()
{
string opAsString;
while(true)
{
System.Console.Write("Enter operation (+,-,*,/) >> ");
char opAsCharacter = System.Console.ReadLine()[0];
opAsString = opAsCharacter switch
{
'+'=> "ADD",
'-'=> "SUB",
'*'=> "MUL",
'/'=> "DIV",
_ => "Invalid"
};
if(opAsString == "Invalid")
{
System.Console.WriteLine("\nInvalid operation, try again >> ");
}
else
{
break;
}
}
double num1;
System.Console.Write("Enter the first number >> ");
while(! double.TryParse(System.Console.ReadLine(),out num1))
{
System.Console.Write("Number not valied. try again >>");
}
double num2;
System.Console.Write("Enter the second number >> ");
while(! double.TryParse(System.Console.ReadLine(),out num2))
{
System.Console.Write("Number not valied. try again >> ");
}
return new OperationData(opAsString,num1,num2);
}
record OperationData(string op, double num1,double num2);
Nothing special here, it is simple Console UI interaction , now lets use call our API from our Client :
string RequestFilePath = "/PATH/Request-File.txt";
string ResponseFilePath = "/PATH/calculatorFiles/Response-File.txt";
while(true)
{
// Using the API
var opData = GetUserInput();
var requestString = opData.op + " " + opData.num1 + " " + opData.num2;
File.WriteAllText(RequestFilePath,requestString);
while(true)
{
var lines = File.ReadAllLines(ResponseFilePath);
if(lines.Length > 0)
{
// Result:number
var response = lines[0];
var parts = response.Split(":");
double result;
if(double.TryParse(parts[1],out result))
{
System.Console.WriteLine("\n --> Result: " + result);
File.WriteAllText(ResponseFilePath,""); // empty the reponse file
break;
}
else
{
System.Console.WriteLine("Error with the calculation API");
}
}
else
{
Thread.Sleep(500);// check for response every 0.5 second
}
}
}
The CalcClient code is here
Try the application, Run the API, then run the Client (change the path, and use the same for both applications), you should find it like this :
Enter operation (+,-,*,/) >> +
Enter the first number >> 43
Enter the second number >> 5.5
--> Result: 48.5
Enter operation (+,-,*,/) >> -
Enter the first number >> 4
Enter the second number >> 1
--> Result: 3
Enter operation (+,-,*,/) >>
Now we get our first simple API, lets see what new concepts we discover :
- API
- Client/Server Pattern : where CalcAPI is the server and CalcClient is the Client
- Communication Protocol : the act that we send the requests and getting the response from files using specific syntax is a communication - - protocol, it is stupid but still one.
In the next article we will make stronger communication protocol that will let as handle multiple request at a time from multiple clients (applications)
Let me know your feedback, and thanks for reading !