In the first part of this series, we've taken a look at creating a twitter bot in .NET that simply listens to particular tweets and retweets them. But we were missing the ability to control what this bot can and cannot listen to. This is the link to the repo (here). It includes the previous changes as well as what will occur during the course of this blog.
For this part of the project, I’ll be adding the endpoints to the existing TwitterBot project. However, some things need to be chopped and changed about: such as migrating the current project to target *.NET 6 * (in order to take advantage of minimal Api’s). Firstly, though, I’ll be exploring what it takes to create the templated Api project in .NET 6.
It would have been all well and easy for me to create an Api project from the template, but I wanted to really note what it takes to create an Api project from scratch (especially for a .NET 6 version). I decided to create two projects and compare both, one is a console project which I will be using to create my sample Api project, and another pre-made Api project generated from the VS template. Both of these projects are in .NET 6.
As I started, I already noted some differences between the standard and the console templates. The first being in the CSProj files, their SDKs are different; the console one is
Microsoft.NET.Sdk while the Api one is
Microsoft.NET.Sdk.Web. This could be where the Program.cs file gets its ability to use the
WebApplication class without any using statement. The second difference is that the console project has an output type property in its CSProj while the Api doesn’t (although it does have the lanchsettings.Json for how it should execute etc).
After I amended my CSProj to look like its Api counterpart and built the projects, the references started to look the same also. It seems to have added the Microsoft.AspnetCore.App reference as a result of a change in Sdk.
I’ve managed to get the first few lines down in order to get the Api project up and running, only these three lines were really needed in the Program.cs file:
var builder = WebApplication.CreateBuilder(args); var app = builder.Build(); app.Run();
These will be entered in order, and we shouldn’t get any errors as the
WebApplicationclass relies on the
.Web Sdk we have in the CSProj (as mentioned previously). Just before the third line, we can create an example endpoint that will help us determine the success so far. Use the
appvariable to access the
MapGet method, which is essentially a shorter version of creating a HTTPGET endpoint in a controller we’d usually have.
app.MapGet("/hey", () => "Hello World”);
As we can see, the first argument is the endpoint we’re establishing, the second argument is a function we pass down which will be invoked whenever the endpoint is hit.
Another cool thing to mention is that the configuration manager works out of the box. All we have to do is access it using the
app variable like so:
app.Configuration["Greeting"]. Try it with the
MapGet method as an endpoint result 👍.
Currently we have two projects, a library and a console project that runs a hosted services for listening to these tweets. Leaning on what we’ve learnt in the previous section, we can also turn this into a .NET 6 project and get it up and running. The steps are the same:
<Project Sdk="Microsoft.NET.Sdk.Web">in the CSProj.
- Most of the nuget packages that we use for hosting and configurations (such as
.Extensions.Hosting) will not be needed anymore and can be removed.
- No need to let the CSProj know that we rely on an
appSettings.Jsonfile and that we need it to be copied to output, we can remove this section as well.
What we should have as a result is this:
Please note that I kept the output type to exe as I like a console but you can feel free to delete the
OutputType line. Also, I made sure in the launch settings that the
launchBrowser property is marked as false as I won’t be needing it for now (possible play with blazor stuff soon? 👀) as this is just an Api project with a running background service.
I also changed the library project into .NET 6, ensuring the
OutputType is Library, changing Sdk type to
.web and, as a result, removing all the unneeded nuget references.
After the setup I made sure to test that:
- Any fake endpoint works
appsettings.jsonproperty can be reached using
Cool, migrated the console project into a functioning api project, time to get the rules endpoints down
This was a very quick way to setup endpoints (as shown in the previous section). It work's right out of the box, no routing and none of the faff needed to configure 😍. However, it doesn’t feel like a clean room for me to have all the endpoints just splatted out there in the Program.cs. So, I created an extension method to help with organization. If it’s for a first iteration, it's just as standard to have it in the same page if that is what is preferred.
It’s correct to assume that it may be too much to separate the Api endpoints from the Program.cs file at this stage as there’s not many. It ended up creating more work for myself in the end while trying to make it look neater. I'm not sure if any of the successful companies ever had the perfect looking code base to begin with, functionality must have come first: and as the code expands it would then be more reasonable to look for ways to optimize the structure. I also feel I’ve done too much, could there have been ego involved in the over engineering aspect? I will reflect on this in another blog 👍
I was able to create Api endpoints for the twitter bot that also has a running background service to listen to tweets. It now has the capability to change its rules whilst listening. The comparison of a .NET 6 console project and a .NET Api template project helped me in the migration stage for the twitter bot, as well as the library. The
.Web Sdk proved to be very useful in getting rid of all of the junk that’s involved with establishing an Api project. However, one thing I will take a look into in further projects, and on a separate blog, is the effect of over engineering and how ego can play a part in it.
Please let me know of any mistakes made during this project and/or this blog, it would be very much appreciated! Now that we have this done, time for part 3, which is looking to host this bad boy onto a Pi 4! Thanks for sticking around, see you then! 👋