 On today's Visual Studio Toolbox, Chris Woodruff and I are going to start our conversation on how you build web APIs. Hi, welcome to Visual Studio Toolbox. I'm your host, Robert Green, and joining me today is Chris Woodruff. Hey, Chris. Hey, Robert. How are you? Good. Welcome to the show. Thank you. Welcome to the cozy confines of Studio B. It's great. Yeah, it's intimate. It's like there should be a fireplace in here. That would be awesome. Yeah. Cozy fireplace. Although it's 90 degrees outside, I'm not sure how much we need a fireplace right now. But come wintertime, that would be handy. You may. You may. Chris is here to talk about web API. Yeah. This is an interesting topic. So web API is basically the modern way of having services running in the cloud that serve up data, typically. And we've done this before. We've had azimx web services and WCF. And then there was web API, which is restful. And we've been doing this for quite some time. Lots of way. RPC, way back in the day. Yeah. But I think it's getting a little bit easier to do. And we're going to look at creating them using ASP Core, which is we'll wind up being faster. .NET Core is really fast these days. We'll talk about how you create them, what they look like. So if you're somebody like me who's kind of coming from the WCF frame, I've written a lot of WCF services. I have a bunch of existing ones that I would love to turn into web API. How do you build a web API? What does it look like? What's the plumbing, the routing, and all the rest of that? We'll talk about that, where you would put all your logic, what that looks like. The benefit, of course, of the web API is that it gives us our world where you have a service running in the cloud. And any client, any client at all, basically passes it a string with a request. The service reads that string, goes off and does whatever it does, whether it's written in, whatever it's written in, who cares. And then packages up your data, sends it back as a string, typically in JSON format. And there's really cool tools for working back and forth between JSON and C-sharp. If you're a .NET developer, if you're not, then you just get JSON back. Everyone can do that with JavaScript. JavaScript uses JSON. The problem with WCF, of course, is it relied on SOAP, which is powerful. But then your client had to have knowledge of SOAP. And if your client didn't, then you would have to write that support yourself who wants to do that. Web API is just completely open and neutral. So we are leveraging the power of the internet. So we're leveraging HTTP. So everyone uses HTTP. So we're actually going to leverage the HTTP calls. So in a sense, you hit the nail on the head. A string comes across. But there's also another piece of information that comes across with it. That would be the HTTP verb. So we have to know if, just like SQL, some people don't like to talk about HTTP and REST with the SQL kind of the idea. But for some people. Get is select. There's a put. There's a post. Add is insert, update, delete. It's crud, right? Whatever the verb is, so what? I do. Because for people that are coming into the RESTful world, it makes things a little bit easier to show them, maybe use some of their knowledge that they have from T-SQL. And then they can kind of understand to be a little more comfortable in the HTTP world. So yeah, so it's actually really easy. They have made, I mean, the ASP.NET Core team has made things extremely simple. All right, so prove that. Prove that. That's a great segue into demos. Prove it. Prove it. Let's write ourselves a web API. So we're going to write an API that connects up to. Is the mouse working? There we go. Uh-oh. This is why the clock's hidden, by the way. There we go. That was strange. OK, I'll pause a little bit. So we're going to build an API against a database that Microsoft created a number of years ago. It's called Chinook. You ever heard of Chinook? So Chinook. Delicious salmon in addition to being a sample database. It is. I love the salmon. But Chinook is a database that has, it simulates a online music store, the front and back. So I like it because it has a whole bunch of cool rock artists and albums and tracks. And it's much more interesting than North Wind. Yes. Anything's more interesting. Sorry, but anything's more interesting than North Wind in bicycle parts. So I'm going to use Chinook. And I actually, Chinook went away. So I don't think Chinook. I have it on my GitHub because it was going away in what's the old of? Going away. I thought data never dies. Well, it doesn't. But what's the old of? Coplex. So Chinook used to be on Coplex. And then it went down. You can still get it, but no one's updating it because Coplex can't be updated. So I grabbed everything. And you can find it out on my GitHub repository in my space. We'll put a link to that in the show notes. So let's do this. So it's really simple. So start like everything. We're going to start with a new project. So we're going to go under .NET Core. And then we're going to do ASP.NET Core Web App. And I'm going to change over and let's browse. Because I like to use, I always put things in my projects folder. And then let's just call it Chinook Core API. Pretty simple. So we're going to say, OK, we've got the next stage. And this is going to be an API. We're going to use ASP.NET Core 2.1. And for this demo, just to make things easier, I'm going to turn off HTTPS. You can leave it on. I mean, you need to leave it on when you actually build something for production. But to make this demo, it's just one less thing I have to worry about. And we're going to show that. If you're making a public API that anyone can use, would you need HTTPS? Yes. Yes. Because remember, Google and with Chrome, and I think Microsoft with Edge, are setting it up where those browsers, if you don't use HTTPS, you'll start getting warnings. Or people accessing your API, well, mostly websites, will start getting warnings from browsers. So it is good to use HTTPS. If nothing else, it's all encrypted between your API and whoever's getting it on the other side. OK. OK. So we're going to say, OK. It's going to stand up everything. Let it figure it out. Let it pull all of its dependencies in. OK. So what I'm going to do to begin with is the project always comes with some initial controller and some initial logic. I'm just going to delete that. We don't need it. And then the other thing is under your project properties, if you go to debug, you will find that there will be an API slash values. Because when you first launch your browser, it wants to go out to that controller that initially created. But we don't want that controller. We're going to create our own. OK. So I'm just going to say API slash. So let's save that. Now we're at a good starting point. So I have a number of packages that I have to install. And again, I copied them from a text file. And we're just going to bring that text file in. Let me go grab that. And so we're installing all the packages that we need for entity framework core. So SQL Server, SQL Server Design, and then entity framework core tools. So you need that, especially when you have an existing database that you're going to be generating your models on. And I like having, I like using existing databases. I'm not really a code-first type of person that does migrations and stuff. I was a DBA for a couple of projects. So I like having real databases that are fully tuned and that run well and have good indexes and stuff like that. I'm old fashioned, I guess. OK, so we have everything that we need. The next thing that we need to do is we need to use a command called scaffold-dbcontext. And I'm going to copy this in. I'm going to paste this in. And I'm going to explain what it is. So it's a command that will generate your dbcontext in all of your entity models. So you give it that command. And then you give it your connection string. So I'm going to run off of a local database. And I'm going to use trusted connection. But then you have to give it the type of database that you're going to be using. So that's where it comes in. And you have to say Microsoft.NEDFrameworkCore.SQLServer. Just say, I'm going to be using a SQL server. If you're using Azure SQL, use SQL server. Same thing, just SQL server. And then the last thing you need to do is give it a parameter called OutputDur. And OutputDur is where you want all of your generated code to be put. And I just say dash outputDur and then space models. And that will create a models class in your project. And then it will put all those new generated files out there. So we're going to run that. It takes a second to go through. Don't worry about that. Sometimes you will have that. If I run it again, sometimes NEDFrameworkCore is a little funny with scaffold beat-dbcontext. So I've had this. I might have missed this part, but where did you tell it what database you were using? So in my connection string, if you take a look here, I have a server, just server dot. And so that just means the local SQL server. And then I have a database just called Chinook. And then I just say trustedConnection equals true. So it's really simple. But you can have a little behind the scenes here. I can't really read that text. Yeah, sorry, no worries. I can increase or I can fix the resolution, I guess. That's good enough. Go ahead. So this will generate all of your models. So at this point, we have our Chinook context. So it should be very familiar. Yeah, and so far, this is pretty standard stuff. It's NEDFramework, right? From NEDFramework6. So it's pretty much the same thing. And if you know NEDFramework6, you should know 99% of Core. So it's pretty, I will say Core is still a subset of, in some ways, a subset. It has some things that 6 doesn't have, but it has lots of things that 6 has that hasn't been brought into the library. And then just a side light, you've got the warning with the squigglies because you have your secrets buried in your code. We did an entire episode on secrets management. I will do that. I always do that because I like to hide my secrets. All right. So we did a whole episode on that a few weeks back. Well, that's awesome because that needs to happen. So we're going to. Would you leave it in there for now, if you want to? Well, actually. Unless you want to do it. Right now, I can just delete it. We're not going to worry about it anymore. Because I'll show you how we take care of it, which you may have already shown in a previous episode. But I'll go through it again for a few more minutes. That's worth repeating now, if you want to show it. So we have this. We have our generated files. Now we're going to go and we're going to work on our startup. So startup.cs is the new core way of standing up all of your services and doing your dependency injection and stuff like that. But first, I'm going to go to my app settings.json. So app settings.json is kind of like, if you remember the old web.config, you can keep a bunch of stuff in there. Well, app settings.json is a JSON file that you can put stuff in there that your project can go out and get. So I just have some trusted code. So I can put my connection string out here. So in here, I have connection strings. And then underneath connection strings in that area, I have ChinookDB. And then the same connection string that we use to generate the files and all the models in the DB context, same exact one. Now you could give it a different one. You could say, you know what? I have Chinook running locally, but I also have Chinook running up in the cloud. And I generate it, and they're both the same. And I want to point my actual APIs up in the cloud. You can do that. Sure. So it's just a connection string. But we're going to keep it local. And now we're going to go over to startup. And we're going to go into configure services. And in here, we're going to put in some more code. You can see I don't like to type. I'm a little lazy. So we're going to put in two lines of code. So in here, and you can see we have some squiggly lines. Let's fix those squiggly lines real quick. So we're going to point to models to get our Chinook context. And then we need to bring in the Microsoft.NED FrameworkCore library for our using clauses. So at this point, we have a line that says, I have a connection string. And I'm going to go through configuration, get connection string. And then it's called Chinook DB. And that's what we did in app settings.json. So we're just leveraging something that's already been given to us in the configuration object that ASP.NET Core gives you. And then we're just going to say, we're going to do dependency injection. And we're going to say services. Our services, we're going to inject our DB context. And we're going to say add DB context. It's a type of Chinook context. And then in there, we're going to say options, use SQL server. And then we're going to give it the connection string. So we are building and setting up our DB context at the very start of our project and injecting it in so that everyone can use it. And no one should be able to get our connection string. It's pretty hidden. And also, if you send this out to Azure, Azure will overwrite it through the web app. If you use a web app service, you can actually overwrite that by having a setting, by putting a different connection string. And it will inject it into here without you having to change any code, which is very nice. So at this point, we have our DB context that's been injected into our application to be used. So let's go back over to the DB context. Before I got rid of everything and on configuring because I don't need that anymore. I've already set up that connection string before I injected it. So that's why I don't really need to have that in there anymore. So at this point, we're pretty good. The last thing that we need to do is have our controllers, right? So we need to know how we're gonna route these HTTP calls to the right controllers and actions in those controllers. Okay, and this is really simple too. You deleted the controller. Because it wasn't the one I wanted. So let's take a look. So if I say add controller, see down here we have an API controller with actions using. One of my favorite features of all time is it'll build a controller for you. Yes, yes. For us lazy people, right? It will at least get you the starting point. The less plumbing I can write the better. I want to focus on my business logic. I do, I want to focus on getting something up and running and then really customizing it to what I want. So model class, we're just gonna go through a couple. Although I do think there should be, I continue to think there should be the ability to create one for all of them. Yeah, so I work at JetBrains and we have some tools like we have Resharper and I'm actually building a plug-in for Resharper to do that. And then it's gonna go for Ryder, which is our .NET ID, but I can't say that too much around the Microsoft world. Around here. Will it work with Visual Studio? It will work with Resharper. So it won't work with, but it will, if you have Resharper installed, it should work with that. So I'm actually building it right now. So, and what that's gonna do is, it's gonna find, just like this does with the dropdown, it's gonna find everything, all these different model classes. And then- I'll tell you what, if you write it as an extension of Visual Studio, I'll have you on the show to show you. Yeah, maybe I can write it- That's your ambition. Maybe I can write it also as an extension. So, oh, you should be able to, it should be that hard. So I'm gonna do album. So album is a model class in our API. And then I'm gonna say my data context class is that Chinook context. And then it will auto generate the controller name. You can change it if you want, but what you have to remember is, because MVC has some conventions, you have to have the model name controller kind of has to go- The plumbing is expecting it's called album controller, so it's easier just to leave it that way. Otherwise you'd have to go mess with the plumbing. Mess with the plumbing, and you have to start really adding a lot of code to start up and so- Now you're moving away from your idea of focusing on- Yes. The code that you need to write. Yes. And you can do it, but yeah, it takes a lot more work and hoops to go through. So it's setting up a controller. Let me close out the models. I'll open up the controller folder so you can see that. And in here, it actually set up our route for us. So remember we had API, so it's API slash controller name, whatever the controller name, which in this instance it's gonna be albums. And it set up everything that it needed. It actually has already set up the internal private read-only property for Chinook Context, which on the constructor uses dependency injection to get that context, and so everything can use it. So we don't even have to write any code to connect our, initially connect our instructors or connect our controllers to our DB context. Now for demo purposes, this is great. I love this. Advanced for production, I don't do it this way. And we'll look at another episode where we'll look at some more advanced architectures. But for this simple demo, this is fine. So we have a command called get album. And you can see that they're all marked up with some annotations. So we have HTTP get. So the one thing that differentiates a controller from traditional MVC, and one that we use in web APIs, is that we decorate our actions with these HTTP verb attributes. So you can see that we have HTTP get. Down here, when we wanna get a single album, we have HTTP get, and then it has an ID that comes along with it. We have a HTTP put. So this will do an update. So if we wanna update an album, we will set up that annotation of HTTP put. And then we have a post. So this will add a new album to whatever data repository that we're using on the backend, SQL Server in our case. And the last one is HTTP delete. So we're gonna use those four. We're gonna leverage those four HTTP verbs for this demo. So the scaffolding built your basic crud. It built pretty much everything that you need to do. And then if you have more advanced data logic, you can just swap out the actual code in here with whatever you want. As long as it's entity framework six, it's .NET Core. So as long as you're writing code that's supported by .NET Core 2.1 and entity framework six, you can do whatever you want in here, whether it's validation, or you're going to different places, or you're massaging the data, whatever you need to do, you can put that code in here. And it does do some validation. So let's take a look at the post. We do come in here and it does check to see if it's valid, if the model state's valid. If it's not, it will send back, it will return a bad request. So a bad request is a 404. So you can either, you can, there are calls to send back, you can send back whatever response code, HTTP response code that you want. But ASP.NET Core has a lot of these simple things that we can do. So if I want a bad request, I can do that. If I want an okay, I can do that. If I want some kind of a 500 error, there's a very verbose call to do that. Or I can have just respond with specific response code and then put my own message into it. So it's quite flexible. But for this, we're going to leave it for that. Now one thing I do want to say, you brought up the business logic. So I don't know if you're like me, but I don't like to delete data in my databases. I like to deprecate it. So I like to just have a bit that says like, on off or visible or not visible. So you could come in here into this delete album action and instead of doing a remove down here, you could just do an update. You could just update that record and turn that back. Or archive it or whatever you want. The point is here that you can. You have control. Right. You wrote some nice templated boilerplate code for you, which may be all you need. Or you can call out to other services, you can, whatever you want. Yep. So let's add one more controller because kind of have to have, I like to have at least two controllers. So let's go down here and we'll do artist. So, and it's already set up. It remembers the last DB context that you use so you don't have to select that. And we get another one. Now I'm gonna clear this out so we don't see that red. I'm gonna build this to make sure it builds. Okay. And then let's see if it will run. Of course it'll run. Why wouldn't it run? It should. It should. It's my least favorite word in all of technology. It should. Okay. It should work. We got a page can't be found, which is good because we actually haven't given it a valid route. Right. So all we have up here is localhost and then the port that we're using and then slash API. So if I said albums, because remember we set up an albums controller and in there we had a route that said that anything from API slash controller name would come into that controller into the corresponding action. And... Voila. Yay. Ta-da. Look at that. And I use a add-in for Chrome that makes my JSON look fine. So if it looks like this that you get, if you get a raw, you have it, don't worry, it's fine. I just have it parsed so I can kind of see. Okay. And we have it. So and if I wanna do, let's say 42 is my favorite number. So if I wanna say give me the album that the album ID is 42, I just say albums slash 42. And that route will go to the get with an ID. And I get back album 42. So it's that simple to set up your web API project. That's all you need to do. It's really simple. And then all you need to do to call it is pass the correct string. Yup. Yup. However your deck gets done. Yeah, and you can use a web browser but you can't do anything other than a get with a web browser. So if you wanna test out and you wanna try out your APIs, there's a few different applications that you can use. I use Fiddler or I use Postman. Okay. And they're both free applications that you can install locally. Postman will run locally or through Chrome. Or through, I don't know if there's an edge. I don't know. But I just run it locally. And I can call and I can say, here's my string that I'm gonna send over and my verb. And I can even set up headers in my HTTP call to set up things like authentication and stuff like that. So we're not even gonna look at all of that but there's a whole rich experience around authenticating around your web APIs. And you can do that yourself or there's third party companies in the partner's ecosystem that will allow you to wrap and help you out with your authentication. And now that you have this API written, tested, proven, you can run it in IIS locally. You can publish it up to Azure. You can run it in a container. There's all kinds of things you can do. Yeah, because it's ASP.NET Core, I can run it on Mac OS or Linux. I can, like you said, I can run it on any number of different instances of Azure. So I can run it on a web app that is of type Windows or of type Linux. I can put it up in a container. And because Linux containers are so cheap on Azure, it's perfectly fine to throw it up on that Kubernetes. You can use it with Kubernetes. So yeah, you can put it just about anywhere. So yeah, so there you go, it's that simple. It is simple. It is. You said earlier, it's easy to do. I said, prove it, you proved it. Yeah, so I do want people, if I ask anyone, if you're gonna be using web API, learn a little bit about HTTP. Sure, absolutely. Yeah. So I think if you're gonna, oh with Xamarin, if you know C Sharp and Xamarin, you can build mobile apps. Of course you can, but you need to learn about iOS and Android. You need to learn about the operating system. If you're gonna build web API, you need to learn some web stuff. But this seems like if you are coming from more of a client side world and you wanna start learning web stuff, this seems like a great place to start. It is, it is. It's, I mean, it's simpler. I think it's simpler than MVC because you don't have to worry about views and you don't have to worry about all that. You're just basically getting those HTTP calls. Right. And sending up your controller and then you can build whatever logic you wanna use. More advanced stuff, you can use a repository pattern to pull out your business logic from your controller actions, which I don't suggest that you put your code, your business logic directly into those actions. I build them into repositories that I can, that I put into other projects so I can kinda share them and I can test them. So the biggest reason why I don't put everything into my controllers is because of testability. Right. Okay. My API calls and my business logic to be independent so I can test and make sure that they're working right independently. Cool. Awesome. So this is gonna wind up being three parts. Hopefully three parts. And maybe more. We are. I will do three now. We hopefully do follow-up ones later. So we just covered the overview. We're gonna do some integration testing next and then you're gonna show us some best practices in part three. Yes. Cool. So hope you enjoyed this one and we'll see you next time on Visual Studio Toolbox.