Let's build a WebAPI service using .NET Core 2.0. It's quite a bit easier than I expected (although I have seen some pretty cool demos of folks building things very quickly). I'm using the command-line interface (CLI) along with Visual Studio Code for editing code files.
I've been working with .NET Core 2.0 for about a week now, and other than having a bit of trouble with some of the samples, I've been enjoying the pieces that are there. I've posted an initial port of my Task sample code, so let's take a look at how I built the service project.
Note: This code is available on GitHub: jeremybytes/person-api-core.
This article shows how to create a service that another application will consume. We'll look at that other application in a future article.
I'm starting with (1) the .NET Core SDK, (2) Visual Studio Code, and (3) the Visual Studio Code C# extension already installed. You can check the resources on the Microsoft announcement article to get the environment set up.
The Project Goal
We'll create a service to provide a collection of "Person" objects using JSON. Here's the ultimate output of our service:
Initializing the Project
As I mentioned, I'll be using the command-line interface (CLI) in a bash window. I'm doing this work on macOS, but this will work just the same in PowerShell on Windows.
I created a folder for my project and navigated to it. I'm using "PersonApi" as my folder name. Once there, we can type
dotnet new webapi
to create a new WebAPI project with the same name: PersonApi.csproj. Here's the output:
When we first start looking at the files in Visual Studio Code, we'll get a pop-up asking if we want to add missing assets:
Just say "Yes" to this. It will add a ".vscode" folder and a few other files to the project.
Here's the initial project layout:
There's not a lot here -- and that's good. We don't have to learn a lot of things to get started with this.
As a sanity check, let's build the project at this point. From the terminal, just type
and we'll see that things are building successfully at this point.
Now let's add a few things to get the data that we want.
Adding the Models
Since this is a WebAPI project, we'll expose our service by creating a Controller. But we'll need a new type and some data for our controller, so we'll start there.
We'll add a "Models" folder to the project. We can do this either from the command line or with the "New Folder" button in Visual Studio Code.
Under the "Models" folder, then we add a new file "Person.cs":
This gives us a new empty file to work with. The "Person" class describes the shape of our data. (This class is available on GitHub: Person.cs. If you copy the code, be sure to check the namespace so that it matches your project.)
Now that we have the "Person" type, we can provide some data for our service. We'll do this by creating a new "People.cs" file with a static method for getting data. (This file is on GitHub: People.cs. Again, be sure to double-check the namespaces if you copy this into your own code.)
Rather than getting the data from a database using Entity Framework (which we'll look at in the future), we'll just use some hard-coded records.
Updating the Controller
Now that we have our model in place, we'll add the controller. The initial project already contains a controller called "ValuesController" (in the "Controllers" folder). Rather than starting from scratch, we'll just re-purpose this one.
First, we rename the file from "ValuesController.cs" to "PeopleController.cs".
Next, we'll update the code in the file. (This is available on GitHub: PeopleController.cs. But it's probably easier to simply type over the code that's already there).
We're only concerned about the "Get" methods of the controller, so we can delete the others. We need to add the namespace for our model
And the we can use the static method from the People class: GetPeople().
The "Get()" method returns the entire collection, and the "Get(int id)" method uses a bit of LINQ to pull out a particular record based on the integer id.
Running the Service
This is all the code we need to write/modify to get our service to work. At this point, we can go back to the command line and type
to run the service:
Note that when we use "dotnet run" on a folder, it looks in the ".vscode" folder for instructions on what to do (this was added for us by Visual Studio Code when we added the required assets above). The default configuration will build before run, so that means that we do not need to have an explicit build step here (although it doesn't hurt).
The really cool thing is that this hosts our service. Notice that it says it's listening on http://localhost:5000. This means that we can navigate to our controller with
and we get the following output:
Changing the Port
The last thing that I want to do is change the port that the service is hosted on. There's no need to change this for our sample, but my other code uses a consistent port for this service: 9874. So I'd like to use the same port here.
To change, the port, we just open up the "Program.cs" file and look for the "BuildWebHost" method:
To change the port, we just need to add another method to the chain:
The "UseUrls" method lets us put in a custom address.
Now we just go back to the command line, press "Ctrl-C" to make sure that the service is stopped. Then use
to kick things off again.
Now our service is hosted at a new location:
We can also pass an ID to our API to get an individual record.
There are lots of cool things that I like about this.
Just a Few Files
The biggest thing I like about this WebAPI project is how few files there are. I started using ASP.NET MVC back with version 2. Back then the default template had about a dozen files/folders when you created a new project. With more recent versions, there are dozens of files, and I have difficulty just trying to figure out which configuration file to use for a particular feature.
The main reason for my difficulty with the full MVC template is that I don't use it very often. And I think about that as a barrier to entry to new developers. If I walked up to the giant template of files for the first time, I think I'd say "this is too complicated" and walk away.
But this ASP.NET Core WebAPI template is really easy to use. This is the final file structure:
That's it. Of course, it helps that I have some ASP.NET MVC experiences, so I understand the conventions around the Controllers and how they are called. But even without that knowledge, I wouldn't be overwhelmed by this folder structure.
I'll be looking forward to digging into ASP.NET Core a bit more.
I really like how easy it is to get a self-hosted website up and running. For many of my demos, I have a self-hosted site to supply data to the application. This is really easy, and I don't have to worry about things like IIS Express or trying to set up a full IIS server on my machine.
A Few Adjustments
There are a few things that have taken me a bit more time to get used to. I haven't been a regular user of Visual Studio Code, so I've been making some adjustments.
For one thing, I'm used to Visual Studio where a "Build" also automatically saves the files first. Visual Studio Code doesn't do that. So I've gone through a couple "why aren't my changes working" when running applications. I just have to get used to saving things before running from the command line.
I've also had to readjust somewhat to using the command line. I intentionally headed for the CLI tools (as opposed to the tools built in to Visual Studio or Visual Studio Code) because I wanted to understand the commands and how they work. Fortunately, I've got quite a bit of experience with bash in my past (although most of it is 15 years in my past). But that bash experience is helping me out quite a bit.
More To Come
The purpose of this project is to port the sample code from my Task & Await talk. This is the service piece. I've already written the Task code which shows consuming an asynchronous method, cancelling the process, and dealing with exceptions. I'll be showing that in the next article. (Hey, look! It's here: Consuming a WebAPI Service with .NET Core 2.0).
And I'll be exploring .NET Core more and more. I'll probably head into unit testing next. xUnit.NET supports .NET Core, and I'm sure that other frameworks aren't far behind (if they're not already there). I've also seen some good demos on Entity Framework Core, so I'm sure that I'll be looking at that in the near futre.
It's been a lot of fun exploring this environment. I'm hoping that things will stay pretty stable at this point because I'm not a big fan of constantly retooling. But we'll see what happens.
Until then, I'll keep exploring, and I'll also be putting out articles to help other folks get around any frustrations that I run into.