SHAWN_CLABOUGH:
Hello and welcome to another episode of Adventures in.NET. I'm Sean Clayboy, your host and with me today, co-host Mark Miller.
MARK_MILLER:
I did it!
SHAWN_CLABOUGH:
You did it. You,
MARK_MILLER:
I'm here, man!
SHAWN_CLABOUGH:
that's what you did?
MARK_MILLER:
Yes, I showed up, man. I've been waiting here all week for you guys to come back.
SHAWN_CLABOUGH:
Have you done anything else all week?
MARK_MILLER:
No, but I figure if I don't close the browser, I'm guaranteed a slot back in the next time.
SHAWN_CLABOUGH:
Yeah, yeah. You know, you've been here long enough, Mark. I think, you know, if you were misbehaving too much, I think we would have booted you out. So I think you're good to go now.
MARK_MILLER:
Maybe
SHAWN_CLABOUGH:
Yeah.
MARK_MILLER:
I can close the browser this time at the end of the show.
SHAWN_CLABOUGH:
Yeah, I won't tell you that you can't get back in, but.
MARK_MILLER:
Okay.
SHAWN_CLABOUGH:
All right, let's bring in our guests for this week. It's Fjodor Sazanovic. Welcome, Fjodor.
FIODAR_SAZANAVETS:
Thank you, nice to be here.
SHAWN_CLABOUGH:
Yeah, so before we get into our main topic of today, why don't you just give us a little bit of your background. You know how you got into development, how you get into working with.NET.
FIODAR_SAZANAVETS:
So it's quite a strange story because I haven't actually done any computer science degree. I don't have official qualification in programming. I did go to university but my bachelor's degree was in environmental biology and then I did master's in environmental informatics which was kind of a mixture of IT and environmental science but I didn't do any actual coding in my degree. I was kind of always interested in computers but the reason why I've chosen biology instead to study computer science and as naive as I was back then I thought that if all of them are going to study computer science then by the time I'll graduate there won't be any jobs so I decided to select an unusual degree and environmental biology just sounded as kind of vaguely useful but as unusual as it could be but then when I found a job after I graduated I was working for a water engineering company And then I got into programming by getting in touch with the programming team that the company had. And I started volunteering to help them to fix various bugs. And gradually I taught myself how to code with some of their mentorship as well. One problem with that particular company was that it wasn't paying very well. I'm talking about paying way lower than a warehouse operator was getting in my local supermarket warehouse. So when I was confident enough to apply for a proper programming job, because in that particular position my job title was not a software developer. I was doing software development in my work, but I was still just assistant analyst for like... hydrology. But then when I was confident enough to start applying for other jobs I did and I got accepted elsewhere, got a job with a proper software developer title and since then just been working as a software developer. Eventually what I started doing as well is writing a lot of content online. I started my own blog, it's available at scientificprogrammer.net. and start creating content. So you found me by finding my article on info queue. So I've got a lot more articles. I wrote some books as well. Regarding.NET specifically, the first programming framework that I used was.NET, but the first language was VB.NET, which is rarely used these days. Because it was gradual progression from me, because by the time I started volunteering with that team To help them to solve their problems. I did know a little bit of VBA Which is the programming language used in Excel to write macros and vb.net was just a natural progression from that into a proper programming language And for my second job I taught myself how to write code in C sharp And since then just been doing primarily that I did work with some other languages as well So for example, I did write a couple of Android apps in Java. I did use Golang to write some Docker extensions I did write some front-end code. I used JavaScript various frameworks and libraries in JavaScript But.NET until this day remains my main area of expertise.
SHAWN_CLABOUGH:
So it looks like you've got a number of books that talk about the easiest way to do something, easiest way to be a software developer, the easiest way to learn design patterns or work with C-sharp and GRPC and things like that. So are most year books and things like that geared towards somebody that's just getting into being a software developer?
FIODAR_SAZANAVETS:
So, the easiest way to become a software developer is the book that is geared towards somebody who is thinking about becoming a software developer. In that book, I basically provide a step-by-step process that worked for me and worked for other self-taught coders that I know. I start the book by telling people the pros and cons of software development, so they can actually decide for themselves whether this career is for them, before they even start doing it. For design patterns, that book is more geared towards people who already know C-sharp, but don't necessarily know the best practices, so primarily junior developers, junior or mid-level developers Design patterns are used in a lot of places and it's something that allows you to solve problems very efficiently. Also, in some job interviews they expect you to know design patterns to solve specific technical problems. If you don't, you're just not gonna get that job. But the problem with design patterns that I found when I was learning them is that they are so hard to learn because the code for most of them just isn't intuitive. enough. So I wrote this book by structuring it in a different way. First I provide the context, so I provide the list of the problems that you can apply design patterns in, and only then I provide implementation examples of each design pattern. So by the time the reader gets to implementation, they will already understand what is used for, and that makes them easier to understand the implementation of design pattern. Because most of the places, there are many good websites like Refactoring Guru, for example, that teach design patterns, provide really good implementation examples. But the problem with the approach that is commonly used is that you look at the implementation first and then you figure out what problems you can apply to, which is probably not the easiest thing to do.
SHAWN_CLABOUGH:
Do you find that certain personality types are more suited to becoming a software developer and being successful at it than other personality types?
FIODAR_SAZANAVETS:
Uh. I'm not sure about personality types, so for example there's no difference between being introvert and extrovert. I've met some introverted software developers, I've met some extroverted software developers. Perhaps the only difference is that extroverted software developers tend to move on to management career afterwards. But I've met some really good extroverted developers as well. As I say to people, if you ever enjoyed playing strategy games on computer, probably going to enjoy software development career because the thinking process is very similar. So if you are good at playing strategy games, you may be good at being a software developer as long as you like it as well. So I would say that software development career is suitable for somebody who likes solving problems and who enjoys technology as well.
SHAWN_CLABOUGH:
Yeah, I'd agree with that too. You know, definitely with the strategy games, you know, I grew up playing a lot of, you know, video games and like risk and even dungeon dragons and things like that. Uh, but I also really enjoyed like puzzles. Like I could never walk past an unfinished jigsaw puzzle without, you know, having to put in one or two pieces before I could move on to do something. It's like, I just like that challenge. So that works well for me.
FIODAR_SAZANAVETS:
Yeah, I think I was the same and most of the developers I know quite a lot of them are into board games I did really like solving puzzles when I was a kid Didn't have many puzzles to solve because I was born in Soviet Union, but Any puzzles I could get my hands on I did enjoy solving
SHAWN_CLABOUGH:
Did you have the Rubik's Cube?
FIODAR_SAZANAVETS:
I did, yes.
SHAWN_CLABOUGH:
Yeah, that was really big. I could never solve it all in my own brain, but it was a fun endeavor. All right, so I think our main topic today is going to be talking about minimal APIs. I think a lot of developers that have been working with.NET for the past number of years might be familiar with creating APIs using controllers, and minimal APIs is kind of a new way of doing the same thing. So why don't you get us started? What's the first thing to know about minimal APIs?
FIODAR_SAZANAVETS:
So minimal APIs are relatively recent, they've been out for a couple of years, but since last November's release of.NET 7 they became almost as powerful as controllers. Prior to.NET 7 minimal APIs were available but there was a very limited range of things you could do with them. You could pretty much write some basic API application with them. Now you can almost do anything with them that you can do with controllers. Maybe 99% of use cases. What are minimal APIs? So with minimal APIs you bind RequestProcessingMiddleware. So for example if you have a program.cs file, the program class, the entry point of your application, you can then just apply those mappings to the app object before you launch your app. So you don't have to have the separate controller classes.
SHAWN_CLABOUGH:
Okay, so you just kind of you set up your your routes and things like that within your program.cs. You know,
FIODAR_SAZANAVETS:
Yes.
SHAWN_CLABOUGH:
I imagine for larger applications that could probably get pretty cluttered and, you know, a lot of things put into there. So is is Minimal APIs suited for some applications better than others?
FIODAR_SAZANAVETS:
Minimal APIs definitely are suited better for smaller applications. If you have an enterprise-grade API with a lot of endpoints, I would say that it's still better to use controllers because it's much easier to manage. Because each controller class has a specific set of endpoints associated with a particular entity, for example. So, yes, in a real life, let's say a banking application with loads of different endpoints. your program.cs will get cluttered very quickly, you will have thousands lines of code in it. There are ways of mitigating that, you can pass your app object to some other file, you can even use several files to do that, you can register your own kind of middleware handlers. But I would say it's probably tidier to do it via controllers still, if your intention is to write many endpoints.
SHAWN_CLABOUGH:
So if that's the case, I don't know how many people are always writing just small, simple applications. So why use minimal APIs at all then and just stick to one method of doing it, just always use controllers.
FIODAR_SAZANAVETS:
Well, it doesn't have to be a tiny application. So if you, for example, have up to 20 endpoints, then minimal APIs are still useful. You can also combine the two. You don't necessarily have to use either or. So for some endpoints you can use minimal APIs, while for other endpoints you can use controllers. Let's imagine a scenario where you have a banking app. You have a controller to manage users data, so it will be user controller. You have a separate controller to manage accounts data or maybe transactions data. And then you have a whole range of other endpoints that don't neatly fit into any categories, that can be handled by your minimal APIs. Or you can have things like health check endpoints. ASP.NET does have a separate... a health check, a middleware to handle health check requests. But you can also have a range of minimal API endpoints for anything that does not neatly fit in any of the categories covered by our controllers. Let's say a webhook. So if your API application expects some webhook from a particular source. then it's only going to be one endpoint for that particular category. So that's a good candidate to be moved into minimal APIs.
SHAWN_CLABOUGH:
Okay. Yeah, I get that. I guess, you know, if you just wanna keep, you know, some basic endpoints that don't do a lot of work, they're just, you know, simple things, you could throw that in as a minimal API. And then for your more complex business logic type endpoints, just throw those into a controller. Is there a lot of differences in the way that you configure? a minimal API endpoint versus a controller endpoint.
FIODAR_SAZANAVETS:
You use different syntax, but functionality-wise it's pretty much the same. Pretty much anything you can do in controllers you can do in minimal APIs. But in minimal APIs since.NET 7 there are some ways of... making it easier. So for example, you can map your request parameters as an object and just insert that one object into your method that is mapped to the endpoint in the minimal API. You can use dependency injection. Obviously, there's no separate class for minimal API because you just attach it to You can use from service attribute and then just inject anything that you registered in your dependency injection. So the way you do it is different, but what you end up with is similar.
MARK_MILLER:
I like the syntax of it. I think the syntax, I like the attributes on the parameters. You were just mentioning dependency injection, and I really like that, the from services attribute at the beginning of that parameter to do that. I think it feels like it's really nice and easy to read. Do you,
FIODAR_SAZANAVETS:
Yes.
MARK_MILLER:
I guess from a, you know, the question of like readability and maybe even getting new developers up to speed. And also from the perspective of testing, can you compare minimal API endpoints versus traditional endpoints? Are there areas where one is better than the other in those categories?
FIODAR_SAZANAVETS:
Readability wise, definitely minimal APIs win, because for controllers you need to know what base class you inherited from. You need to know other things. You need to know how to return parameters. What's the difference between action results, like JSON result, those kinds of things. With minimal APIs, framework handles all that for you. So it's a very simple and not very verbose, very concise mapping. I think the idea for minimal APIs came from Node.js because this is how the endpoints are mapped in Node.js but Node.js came first so yeah, in terms of how steep the learning curve is, minimal APIs are definitely better way easier to learn than controllers In terms of testing, there's not much difference because we don't tend to call the endpoint methods directly when writing unit tests. A good way to do it would be to have some kind of service being injected into it, which contains all the business logic, and you would then execute unit tests against that service, not against the endpoint itself. But to test the actual endpoint, you would normally do some kind of integration test, which ASP.NET Core allows you to do. It has some libraries. So you can actually launch integration tests from the same pipeline as unit tests. And because you're calling HTTP endpoint, it doesn't make any difference whether it's on the controller or if it's mapped in program.cs file. Yeah, it doesn't necessarily have to be mapped in program.cs file, because you can
MARK_MILLER:
Right.
FIODAR_SAZANAVETS:
use separate classes to do that. But the main point is that it uses those GETs. mapGet, mapDelete, mapPost, mapPut, those methods and it applies them on the app object.
MARK_MILLER:
Right? So for maintainability of complex systems with a lot of endpoints, traditional endpoints win. For readability and bringing new developers up to speed, minimal API wins.
FIODAR_SAZANAVETS:
Yes.
MARK_MILLER:
And it's no difference on testing.
FIODAR_SAZANAVETS:
No difference on testing, yes.
MARK_MILLER:
Any other benefits or drawbacks you see when you compare the two?
FIODAR_SAZANAVETS:
Any benefits to Dropbox? Well, controllers still have more functionality. I can't remember off the top of my head what functionality is missing in minimal APIs. But it's not as complete as controllers yet, because controllers existed for a very long time, even before.NET became platform-independent, when it was Windows-only. framework, it still was using controllers, it still had web API in ASP.NET. So that is perhaps the biggest drawback of it.
SHAWN_CLABOUGH:
Yeah, I like how, you know, what makes it really readable is that it's using the fluid syntax for the configuration of everything. And, you know, looking at your article, you talk about request filters, things like that, that you can put on an endpoint. How do those work?
FIODAR_SAZANAVETS:
Request filters allow you to insert request processing pipeline into the endpoint itself, basically. So traditionally you would have some kind of request processing pipeline in the middleware itself, and then you have some logic in it that decides. what endpoints to apply it to, which is not very neat if you deal with controllers. Controllers normally didn't have that functionality unless you implemented it yourself manually. But with minimal APIs there are some delegates that you can attach to your endpoint mappings that will do it on per endpoint basis. So, for example, you can use it for things like restricting access to specific users. It basically acts as a filter and also as something that modifies requests before it reaches the business logic.
SHAWN_CLABOUGH:
So things you might normally just put within the controller, you know, the method body to handle something. You can just do this within the fluid syntax of a minimal API.
FIODAR_SAZANAVETS:
Yes, so previously there were ways to do it all, but you had to do everything yourself. You had to write all the logic manually, but with minimal APIs, it provides you with some delegates that you can attach methods to and some nice syntax to execute it as well.
SHAWN_CLABOUGH:
So can you also do things like handling file uploads or things like that within Minimal API endpoint?
FIODAR_SAZANAVETS:
Since version.NET 7, yes, you can. It's a fairly recent feature, only been available since November. Well, it was available before when it was still in preview. But it has been production ready since November 2022. But yes, now you can upload files as well.
SHAWN_CLABOUGH:
And you can get access to all the multi-part form data that's coming in. So you can get, like if you got multiple files, but you also have form data that comes along with it, you can get all that right in your endpoint there.
FIODAR_SAZANAVETS:
Yes.
SHAWN_CLABOUGH:
Nice. Anything else that we haven't covered about minimal APIs that we should let our listeners know about?
FIODAR_SAZANAVETS:
Let me think about it. So you can do dependency injection, as I mentioned before, even though you don't necessarily have to have a separate class for that because with the recent versions of.NET, you can use dependency injection on parameter basis.
SHAWN_CLABOUGH:
Is there any performance differences between the two? Or is it just because it's a more lightweight endpoint that's not gonna do as much heavy business logic that it's just gonna be faster because of that, but not really faster because of the technology behind it. The technology behind it.
FIODAR_SAZANAVETS:
I cannot provide a detailed answer on that, but my guesstimate is that they are better at performance because they have fewer things to load. Because with controllers you have to load the entire class. It inherits from a base class as well. So I would imagine that performance would be slightly better with minimal APIs, but probably not by a lot. Because most of the things that affect performance with these kind of endpoints is the network itself, things like network latency.
SHAWN_CLABOUGH:
Ah, okay. Got it, got it.
FIODAR_SAZANAVETS:
But.NET 7 itself has higher performance than its predecessor.
SHAWN_CLABOUGH:
Is there any changes in.NET 8 that you're aware of?
FIODAR_SAZANAVETS:
Haven't been following.NET 8 closely yet.
SHAWN_CLABOUGH:
Okay. I think what else we wanted to cover today and talk about a little bit is Signal R. You know, I've used SignalR once in an older full framework application that I worked on. And the reason that I needed SignalR for that application is we often had people editing a form where multiple people were in there, you know, making changes at the same time. And rather than doing a locking mechanism where if somebody says, hey, I'm going to edit this form, it would lock it and nobody else could make changes. And then, of course, they would forget to unlock it. So I didn't want to go that route. So I set up signal R so that you know as people were making changes to this form They would see any changes that somebody else made But that was you know, that was probably done at four point seven four point eight days I'm sure there's things a lot different now. So you know Tell us about you know, signal R and what its latest and greatest things it can do
FIODAR_SAZANAVETS:
So, signal R has been completely rewritten since 2016 when.NET Core became first available. So the version of SignalR that ASP.NET Core uses is very different from the original SignalR that came with.NET Framework. SignalR is an inbuilt library, it's available with ASP.NET Core Framework, you don't need to install any NuGet packages, nothing like that. What it's used for is to enable real-time two-way communication between the client and the server. So it's a perfect library to build interactive apps with. So if you expect somebody to send you a message, if you expect to see it in real time Things like delivery tracking on the map because server will be sending Data to the client so both client and the server communicate with each other, but it's not necessarily happening with request response So with signal R there is a persistent connection between the two and message can travel either way while the connection is available. Client initiates the connection but once the connection is established the messages go both ways. Under the hood it uses one of three transport mechanisms. By default it uses WebSocket. The second best mechanism that it will use if you explicitly configure it or if it cannot use WebSocket for some reason is service and events. And then failing that, it uses long polling because anything supports long polling, but it's not as efficient as either of those two mechanisms. With WebSocket, normally the way to program WebSocket would be... It wouldn't be very easy because what you have to do is disassemble message into bytes and reassemble it on the other end as well. With SignalR everything works... So the library does everything for you everything works as if you are doing RPCs remote procedure calls. You program the client with some named event triggers and you program the server with some methods that client can invoke. And the way you write the code is almost as if client is calling several methods directly and vice versa. So I wouldn't say it's easy because nothing in programming is truly easy, but it makes it a lot easier to implement something as complex as a two-way communication between the client and the server. I use it quite a lot, I wrote quite a lot about it, on my website there are quite a few articles about it I wrote a book about it because I've been searching for books on the subject And there weren't any good books available, one that I found was on the.NET Framework version, which is outdated now So I wrote my own Plus, when I was using it myself, when I was learning how to use it I found that not all documentation covered all the cases that I needed to find out about So I included those in the book as well The most interesting project with SignalR that I've been involved in was to get it to control a cluster of IoT devices. It was specific for the railway industry. We have this setup where each platform had a device and those devices were connected to the server hub. The purpose of this device, there were several purposes, but the main purpose was to make the train announcements. So, a certain time before train is due to arrive at the platform, the device had to make the announcement, it had to play audio at the platform. But it solved many problems. So for example, traditionally on the train stations They will get the actor to record all the station names and then just glue them together into the message We did text-to-speech. So the server would send the request to text-to-speech server Would get the mp3 back and would send it to the device on the platform server knew all the train movements in real time the device on the platform didn't and to send the audio when the device is due to play it. But another.
MARK_MILLER:
So if the train was late, you'd get a specific message saying when that train would come in.
FIODAR_SAZANAVETS:
Yes,
MARK_MILLER:
Nice.
FIODAR_SAZANAVETS:
so client didn't know anything about that, client was fairly simple The role of the client was to play audio when it's requested to play audio And also to know that other devices in the vicinity are playing audio at the moment, so they wouldn't talk over each other. So, for example, if device at platform 1 starts making train announcement, and then device at the platform 2 is about to start making announcement, it will not announce anything until the first device finished. That solves another problem which is common at train stations, especially in England, where it does actually happen.
MARK_MILLER:
where you get two different announcements at the same time.
FIODAR_SAZANAVETS:
Two different announcements and not only that but sometimes you're trying to hear the train announcement and the device that is closest to you is Actually talking about something like smoking is not permitted at the station
SHAWN_CLABOUGH:
I'm going to go
MARK_MILLER:
Oh,
SHAWN_CLABOUGH:
to bed.
MARK_MILLER:
wow. So
FIODAR_SAZANAVETS:
We
MARK_MILLER:
this
FIODAR_SAZANAVETS:
solve
MARK_MILLER:
is
FIODAR_SAZANAVETS:
that problem
MARK_MILLER:
so this is cool. So that means that the device at platform one, which is across from the device at platform two, has to know when platform two is talking and when it's done. But
FIODAR_SAZANAVETS:
Yes.
MARK_MILLER:
it doesn't need to know about devices that might be out of earshot far away. So it kind of needs to know who it's next to.
FIODAR_SAZANAVETS:
Yes, so that was configured on the server. We have this table which basically told each device what the nearby devices are. So, devices were split into clusters. So there was this concept of clusters. So any devices in the cluster, the ones that are located fairly close to each other. Sometimes it is the entire station, sometimes it's sections of the stations. It depends on how big the station is, because some stations are just four platforms, in which case. So,
MARK_MILLER:
Yeah,
FIODAR_SAZANAVETS:
we have
MARK_MILLER:
I
FIODAR_SAZANAVETS:
a couple
MARK_MILLER:
love
FIODAR_SAZANAVETS:
of different
MARK_MILLER:
this.
FIODAR_SAZANAVETS:
platforms.
MARK_MILLER:
I love this problem because it's a great problem because you can solve this in a bad way If you don't care about the customer experience, you can
FIODAR_SAZANAVETS:
Yep.
MARK_MILLER:
solve it in an easy fast bad way Right, but if you if you care about it, it's it's it's trickier Right
FIODAR_SAZANAVETS:
Yeah.
MARK_MILLER:
like and also it's interesting too, right? So In order to get good unit testing on this experience, I would imagine that you would have to create kind of a mock of the device to some degree, and this ability to check whether other ones are talking or not, whether other ones in the same cluster are there.
FIODAR_SAZANAVETS:
It was easy enough because.NET Core is platform independent, OS independent framework. You could actually use that technology on Windows as well, on Windows and Linux, on any development machine. So you can emulate two devices by using software emulation on your machine and test it this way. Of course, we run proper tests as well with proper devices, like when there are two devices in the room, if they recognize each other. But yeah, because of OS independent nature of the framework itself, it was fairly easy to test.
MARK_MILLER:
Yeah, it's a fun project.
FIODAR_SAZANAVETS:
Yeah,
MARK_MILLER:
I love it.
FIODAR_SAZANAVETS:
it was one of my favorite projects that I did.
SHAWN_CLABOUGH:
So there's all sorts of different clients that you could be serving to. You could be a web browser client, IOT client, desktop client, anything like that. Does it require different configurations depending on the different client that you're connecting to the backend server?
FIODAR_SAZANAVETS:
It doesn't require a different configuration on the server. The server doesn't care about it. It just knows that client is talking to it. But it requires technology specific library. Microsoft supports Java,.NET and JavaScript. But there are also plenty of other... There's a Go library that was created by somebody, there's a Flutter library as well. Those aren't official libraries, but it's fairly... I wouldn't say easy, but it's not prohibitively difficult to write your own library, to create your own SignalR client. Because the message in format itself is just a JSON which has specific fields like method name, parameter names and so on
MARK_MILLER:
Yeah, I used SignalR to speak with, I guess we call them chat bots that I created for my Twitch stream. And one of the things we were doing is we were rolling dice for the Dungeons and Dragons game.
FIODAR_SAZANAVETS:
Mm.
MARK_MILLER:
And so I would make a call from the server that would basically be, roll the dice, this is the damage, this is the number of dice, this is the type. And then the chatbot overlay, the overlay would be, would roll the dice out in 3D. And if it was like a fire damage, the dice would be on fire. And if it was cold damage, there'd be a winter cloud going. And once the dice stopped rolling, it would then send a single R signal back, send a message back. And the chat is written in JavaScript and TypeScript. But it would send a message back to the server, which is written in C sharp, and said, here's the die roll. Here's what all the numbers are.
FIODAR_SAZANAVETS:
Yep.
MARK_MILLER:
And that complex part of communicating back and forth was handled transparently behind the scenes without me having to learn anything. just by using SignalR. So I really enjoy that experience, right? And the reliability of it is, that code still works and I haven't touched it in like two years.
FIODAR_SAZANAVETS:
Yeah.
MARK_MILLER:
So good.
FIODAR_SAZANAVETS:
You can scale it as well, you can use it in large scale applications, which I thought at the beginning was impossible because how can you maintain persistent connection, especially if you need to send message to a specific client if you have, let's say, chat application or social network where you need to send a message to a specific client if you have millions of them. But apparently there are two ways of doing so first of all, if you are hosting your own signal application, you can just use Redis as a backplane So all the instances of the SignalR Hub that you have will communicate with each other when the message comes in one instance and you have to send it to the client connected to another instance. It will still happen as if it's all SignalR Hub instance on the server. And the second way is Azure SignalR Service, which does quite a lot of stuff for you. So you don't even have to write as much code.
SHAWN_CLABOUGH:
So it seems like there could be some security concerns with setting up SignalR to make, you know, making sure that the right person or the right group gets the right messages, things like that. So what's security like and testing like, I guess with SignalR?
FIODAR_SAZANAVETS:
So with SignalR you can secure your communication by doing standard OpenID connect or any other security protocol that ASP.NET Core supports. And also by choosing specific user there's a mechanism of identifying them by randomly generated GUID. So that's going to be your client ID. So then it's up to you as an application developer to make sure the message does not leak to the client that you did not intend to send it to. So you have to have some mechanism in place to map a specific message to a specific client ID. But the communication itself, so if it's intercepted, because you still use TLS certificate, you still do it over HTTPS, you still have all the security in place, like single sign-on, any other security, it supports certificate security, for example, in the case with IoT devices, where you cannot just authenticate as a user, you can configure certificate authentication.
SHAWN_CLABOUGH:
Okay, so what's kind of, you know, this all seems all great and simple, but there's probably gotta be some complexities in there. So when somebody actually goes in there and tries to work with SignalR, what's the biggest challenge that they're gonna find in implementing something like this?
FIODAR_SAZANAVETS:
The biggest challenge for maybe 90% of use cases is going to be fairly straightforward. One challenge perhaps is to figure out whether both client and the server in the setup support WebSocket. It's not necessarily a challenge, but sometimes you have to configure... communication protocols explicitly on either client or the server Because you might end up in a situation where if you just allow signal R to apply the default Transport mechanism, which is web socket You might end up in the situation where your client is trying to send the messages But your network or something else on the host does not allow you to
SHAWN_CLABOUGH:
And SignalR isn't smart enough, I guess, to figure out that and fall back to some other protocol.
FIODAR_SAZANAVETS:
In most cases it's smart enough to fall back to a certain protocol. I just had one scenario where it was IIS server, where WebSockets were not enabled by default. There was some kind of problem, but it was a while ago, so I don't remember the nature of the problem. But I remember that in that particular scenario I had to configure transport mechanisms explicitly.
SHAWN_CLABOUGH:
I
FIODAR_SAZANAVETS:
But
SHAWN_CLABOUGH:
see.
FIODAR_SAZANAVETS:
it's more for advanced cases, so for example I have been in a situation where SignalRub Hub needed a client that was a pure WebSocket client The technology was limited, so there was no option of using the SignalRub client library on that client It was also made by our partners, so we did not control the software on that client So we need to figure out how to connect a pure WebSocket client to SignalR Hub It ended up being relatively simple, but we figured out by just connecting our own client via WebSocket and just capturing the packages that we exchanged So you have to send some handshake package that SignalR understands before you can connect your pure WebSocket client I did write an article about it and it's also covered in my book
SHAWN_CLABOUGH:
Okay. So is there any limitations to SignalR? I mean, can it do things like streaming rather than just message sending?
FIODAR_SAZANAVETS:
It can do streaming, yes. I haven't used streaming personally that much because, for example, with gRPC streaming, the reason why it exists is to... Send messages from the server or from the client to the server asynchronously, but SignalR does it by default anyway So in most of the cases streaming is redundant, but there is both client initiated stream and server initiated stream In SignalR available. You can't use SignalR to stream videos, stream audios. It's not as good perhaps for streaming just individual objects, individual messages But streaming can still be very useful in SignalR if you need to receive a series of messages from either client or the server in a very specific order if there is a particular piece of business logic, because if you send them as individual messages you trigger one piece of business logic. If you send them as a stream, they all are going to come to the same method so if you need to get the method to capture several messages in a specific order This is a scenario where streaming will be useful.
SHAWN_CLABOUGH:
Is there any sort of limitations or a point at which you have so many people connected to an endpoint that it starts to drag things down?
FIODAR_SAZANAVETS:
There is a limitation. I can't remember the number of maximum connections off the top of my head But as I mentioned previously you can scale it out. You can use either Redis backplane or a signalized service So basically there is a limitation of how many Active connections you can connect to one server instance But if you scale it out, then you can have multiple instances. So it's not going to be a problem anymore
SHAWN_CLABOUGH:
Okay,
FIODAR_SAZANAVETS:
Sorry.
SHAWN_CLABOUGH:
so if you're fearing some sort of a server farm or something like that, and you need to make sure that they're all, communicating with each other and know what messages have been sent or messages that are coming in, you can use some sort of a backplane or something like that.
FIODAR_SAZANAVETS:
Yes, so if you host it yourself you would use something like Redis Backplane. It's a technology supported by SignalR out of the box. So Redis is going to be used as a backplane to exchange the data between the instances of your server-side SignalR hub. So as I mentioned previously, for example, if you have a chat application, if it's a huge chat application with a million users or so on. If one user that is connected to one instance of the hub is trying to send a message to a user connected to another instance, the SignalR backplane will know about it. It will know which specific SignalR clients are connected to which instances of the hub. And it will redirect the message to that specific instance of the hub. And it will work exactly the same way as if you only had one hub instance.
SHAWN_CLABOUGH:
All right, cool. I guess we're running towards the end of our time here. Is there any last few things that you wanted to throw out there and talk about before we move on to picks?
FIODAR_SAZANAVETS:
Uh. One technology that I've been using quite a lot as well is the gRPC and gRPC is the first citizen in.NET. It's been like that since.NET 3, if I remember correctly. And one cool feature that has been added to gRPC functionality in.NET 7 is JSON transcoding. Because previously, if you needed to create endpoints for gRPC and for REST API, endpoints. With gRPC JSON transcoding, what you can do is just apply a couple of config files and your gRPC endpoint can be used as a REST API endpoint as well. So you don't have to write as much code, but you will be able to access it from a Swagger page, you will be able to just send standard HTTP requests to that endpoint. And you will also be able to access it from the browser Because gRPC is not available from the browser unless you apply certain third-party libraries like gRPC web
SHAWN_CLABOUGH:
Yeah, I tried to work on a gRPC for one of my projects about a year ago. And that's one of the limitations that we ran into is we wanted to use it for client server communication. And it just became too much, you know, to get that working. You know, it seemed better suited at that time for server to server communications rather than, you know, client to server. So that it sounds like that might've gotten better over the past year.
FIODAR_SAZANAVETS:
So basically, even though modern browsers support HTTP2, which is required for gRPC, they don't support all HTTP2 features. And some of the features that browsers don't support are actually the features that gRPC needs. So this is the reason why browsers don't yet fully support gRPC. So you have to find ways around it. But with JSON transcoded, you don't have to use gRPC to access the same endpoints that your other services connect to via gRPC. So, for example, in the scenario where you have an application where you will be accessing from browser via REST API and you will be accessing from some microservice via gRPC. Previously, you had to write two separate endpoints for that. With JSON transcoding, you only write one gRPC server implementation and you will have two endpoints, two for the price of one essentially.
SHAWN_CLABOUGH:
Okay, nice. Yeah, I think that covers things pretty good about minimal API, SignalR, a little bit about gRPC. So I guess we should move on to picks then. Mark,
FIODAR_SAZANAVETS:
Let's do
SHAWN_CLABOUGH:
what's
FIODAR_SAZANAVETS:
it.
SHAWN_CLABOUGH:
your pick? Mark, what's your pick?
MARK_MILLER:
I think I'm going to throw out my own product here, which I manage, but it's free. So don't think this is a marketing thing. Because we just are releasing a new, it's free, it sits inside a Visual Studio, the product name is Code Rush. We just released a new feature that I obsessed over in the creation of, and I think it's really well done. The feature is called Jump Codes, and it allows you to go to any screen with code on it that you can see on your monitor with just the very fewest keystrokes. So you might have multiple monitors with multiple windows of Visual Studio code, Visual Studio code windows up, and you just. hit a key to invoke it. Wherever you're looking, the code appears. You type in the code that you see and the caret's there. So yeah, that's what I'll say. I'll say code rush.
SHAWN_CLABOUGH:
Yeah.
MARK_MILLER:
Go get it kids if you're not using it. It's free, I'm not getting any money from this.
FIODAR_SAZANAVETS:
Thank you.
SHAWN_CLABOUGH:
Are you working on Code Rush AI?
MARK_MILLER:
I am. That was my second choice was I've been working with OpenAI and I've been discovering some really interesting things about it. It's really, really interesting and where it's going is gonna get even more interesting. Like today I said, simplify this method for me. I gave it a method that was. overly complex. I wanted to see if we could figure out how to simplify it. It comes back with a pretty good job. It essentially nailed everything except for it at it. He kept the private keyword, which is by default it's private anyway. So it didn't need that. But I was like, Whoa, we're getting, we're getting right on the edge here of some very cool stuff. Right. And I'm actually, I'm actually right now writing, I think I'm working on about three or four different AI based features for Code Rush that I'm excited about, super excited about, but I'll blab about those later.
SHAWN_CLABOUGH:
Okay, yeah, I think instead of AI being artificial intelligence, I think it should be like assistant intelligence, you know,
MARK_MILLER:
Sure.
SHAWN_CLABOUGH:
it's kind of helping
FIODAR_SAZANAVETS:
Yeah.
SHAWN_CLABOUGH:
you out with things, you know, you
MARK_MILLER:
Yeah.
SHAWN_CLABOUGH:
know.
MARK_MILLER:
Well, I think we did the AI show a while back. I think you weren't here for that, Sean.
SHAWN_CLABOUGH:
Yeah,
MARK_MILLER:
But
SHAWN_CLABOUGH:
I wasn't
MARK_MILLER:
I think
SHAWN_CLABOUGH:
here. Yeah.
MARK_MILLER:
on that show, I was the guy saying game over for my ultimate prediction. But I did say it's going to get better before it gets worse. It's going to get really good before it gets worse. It'll be like, I think as developers, each developer will be like they're managing a team of developers. Right. They'll be able to say, work on this task. Work over here. Create this for me. Do that piece right there. And those little tasks will all be working and maybe communicating with each other and kind of like planting seeds and growing the code while you do whatever you have to do. Right. I think that's where we're gonna...
SHAWN_CLABOUGH:
Yep, that's why there's all those job postings for prompt engineers.
MARK_MILLER:
Hmm sure. Well, it's not just prompting though that the thing that is really interesting that I've learned in the work that I've been doing in the exploration is it's also conditioning the response that comes back because the response that comes back, you know, might be 80% awesome like 80% really remarkably awesome and time saving and maybe 20% what? Like that. And so you can't tell really the AI, you could tell the AI, I don't need the what. But the AI likes to be kind of, it likes to express itself a little bit. It likes to put those things in there. So you kind of need a secondary level, you need the prompting engineering at the beginning, and you need a secondary level at the next stage. And if you're in the middle of a conversation, you need some kind of. correction prompt as well if it goes off if it strays yeah I would like take over the picks conversation with all this talk
SHAWN_CLABOUGH:
No, no, no,
MARK_MILLER:
but
SHAWN_CLABOUGH:
just,
MARK_MILLER:
it's it's
SHAWN_CLABOUGH:
it's
MARK_MILLER:
exciting
SHAWN_CLABOUGH:
just so interesting. Yeah, and exciting. Yep, definitely,
MARK_MILLER:
Yeah.
SHAWN_CLABOUGH:
definitely. All right, so my pick this week is an application that I use. I just recently started using for managing the softball team that I'm on. You know, I've always. You played softball for slow pitch softball for about 25 years, things like that. Manage a team for probably 20 years, things like that. And it's always been, you know, trying to keep track of who's coming to the next game. And is everybody going to show up? You know, do I have enough players to, to put a team out there or do I need to find substitutes, things like that? So I was looking for something that will help me do that. And I came upon an application called bench app. And it's really nice because it lets me post when the games are, and then each person is going to get prompted. You know, are you attending? You're not attending things like that. But it also has built in chat. So I don't know if they're using signal or anything like that. So it allows all the team to chat to each other so they can, you know, let us know. Hey. I'm going to be out because of this reason I'm on vacation or taking a trip or, you know, something happens or whatever they can, you know, let me know last minute rather than, you know, me just, you know, trying to keep track of my email while I'm sitting there at the field going, I still have everybody here. So if you work with sports teams, it doesn't have to be softball, community type of sports team, organization, things like that. Check out BenchApp. Hi Fjordur, do you have a pick for us?
FIODAR_SAZANAVETS:
And my pick will be underrated library slash command line tool made by.NET team called ml.net, which is basically a.NET based tool to train your machine learning models. It supports a wide range of machine learning tasks like binary classification, image classification. Out of the box you can do supervised and unsupervised learning with it. The best thing about it is that it allows you to learn machine learning as a developer. If you don't have any data science experience at all, it basically just makes the learning curve much gentler. Because to train your model you don't have to do much. It will select algorithm for you. It will assess several algorithms It will then Select the one that produced the best score the best fitting model You can of course then go ahead and learn some more things about machine learning But you can basically start using it just by knowing the most basic things about machine learning and nothing else. Basically, you don't have to be a data scientist. I've been using it quite a lot in my spare time. I've been playing with it quite a lot and it's just amazing. I'm just surprised it's not used in many more projects that it's used in. I did actually propose to my CTO to use it for anomaly detection. to create automated alerts and things like that because it's quite good for this task And you can't do deep learning with it as well, you can't actually construct neural networks with it as well
MARK_MILLER:
Peter, can you put a link to that in the chat and then we'll make sure the listeners see that too as
FIODAR_SAZANAVETS:
Yeah,
MARK_MILLER:
well.
FIODAR_SAZANAVETS:
just give me a second.
SHAWN_CLABOUGH:
Yeah, that sounds like maybe a topic for a future episode. So we'll have to talk about, I think we've really got
MARK_MILLER:
Yeah.
SHAWN_CLABOUGH:
into machine learning on our show in the past. So definitely
FIODAR_SAZANAVETS:
Let
MARK_MILLER:
You
SHAWN_CLABOUGH:
something
MARK_MILLER:
know
FIODAR_SAZANAVETS:
me
MARK_MILLER:
what?
FIODAR_SAZANAVETS:
just
SHAWN_CLABOUGH:
that
FIODAR_SAZANAVETS:
find
SHAWN_CLABOUGH:
could
FIODAR_SAZANAVETS:
the
SHAWN_CLABOUGH:
be
FIODAR_SAZANAVETS:
official
SHAWN_CLABOUGH:
a topic.
FIODAR_SAZANAVETS:
website because Microsoft is not very good at indexing the official website. This is why I'm just getting a lot of tutorials from third parties. But yeah.
SHAWN_CLABOUGH:
Yeah.
MARK_MILLER:
You know, Sean, I'm thinking about building my own robot and machine learning it to teach it that it's human, like me, so that
SHAWN_CLABOUGH:
Hey
MARK_MILLER:
when the robot overlords come to get me, my machine robot will be on my side. And it'll be like, maybe hold a mirror up to it, and then it'll look at me like I betrayed it. And it'll come kill me. Sean, it's going to kill me.
SHAWN_CLABOUGH:
No, no, he's the robot. I'm a human. No, he's the human. I'm the robot.
MARK_MILLER:
I just try to find a way to
SHAWN_CLABOUGH:
Hehehehehehe
MARK_MILLER:
survive the oncoming doom that I'm helping, you know, rush in. That's all.
SHAWN_CLABOUGH:
Yeah,
MARK_MILLER:
Thanks, John.
SHAWN_CLABOUGH:
OK. All right, Feodor, if our listeners have questions, we'll definitely put some links to your site in the show notes. But if they want to reach
FIODAR_SAZANAVETS:
Yeah.
SHAWN_CLABOUGH:
out to you, what's the best way to get in touch?
FIODAR_SAZANAVETS:
The best way to get in touch is via LinkedIn. I'm quite active on LinkedIn. I'm also available. There's also email address I can share with you, which is f.sazanovec.gmail.com This is my main email address.
SHAWN_CLABOUGH:
Okay.
FIODAR_SAZANAVETS:
But LinkedIn is probably the best place because I check it every day. I post on it quite actively.
SHAWN_CLABOUGH:
Okay, sounds good. Thanks for being on the show today, Fjordur. It was great to talk with you and some good topics. Hopefully our listeners got some good information.
FIODAR_SAZANAVETS:
It's been my pleasure.
SHAWN_CLABOUGH:
Yep.
FIODAR_SAZANAVETS:
Thank you for watching me.
SHAWN_CLABOUGH:
Yep. And if our listeners have feedback for the show or topic suggestions, I'd love to hear from you. You can get me on Twitter. I am at dot net superhero. And thanks everybody, and we'll catch you on the next episode of Adventures in.NET.