Hands-On RESTful Web Services with ASP.NET Core 3 - Samuele Resca - E-Book

Hands-On RESTful Web Services with ASP.NET Core 3 E-Book

Samuele Resca

0,0
36,59 €

-100%
Sammeln Sie Punkte in unserem Gutscheinprogramm und kaufen Sie E-Books und Hörbücher mit bis zu 100% Rabatt.

Mehr erfahren.
Beschreibung

Get up to speed with the latest features of C# 8, ASP.NET Core 3 and .NET Core 3.1 LTS to create robust and maintainable web services




Key Features



  • Apply design patterns and techniques to achieve a reactive, scalable web service


  • Document your web services using the OpenAPI standard and test them using Postman


  • Explore mechanisms to implement a secure web service using client-side SSL and token authentication



Book Description



In recent times, web services have evolved to play a prominent role in web development. Applications are now designed to be compatible with any device and platform, and web services help us keep their logic and UI separate. Given its simplicity and effectiveness in creating web services, the RESTful approach has gained popularity, and this book will help you build RESTful web services using ASP.NET Core.






This REST book begins by introducing you to the basics of the REST philosophy, where you'll study the different stages of designing and implementing enterprise-grade RESTful web services. You'll also gain a thorough understanding of ASP.NET Core's middleware approach and learn how to customize it. The book will later guide you through improving API resilience, securing your service, and applying different design patterns and techniques to achieve a scalable web service. In addition to this, you'll learn advanced techniques for caching, monitoring, and logging, along with implementing unit and integration testing strategies. In later chapters, you will deploy your REST web services on Azure and document APIs using Swagger and external tools such as Postman.






By the end of this book, you will have learned how to design RESTful web services confidently using ASP.NET Core with a focus on code testability and maintainability.




What you will learn



  • Gain a comprehensive working knowledge of ASP.NET Core


  • Integrate third-party tools and frameworks to build maintainable and efficient services


  • Implement patterns using dependency injection to reduce boilerplate code and improve flexibility


  • Use ASP.NET Core's out-of-the-box tools to test your applications


  • Use Docker to run your ASP.NET Core web service in an isolated and self-contained environment


  • Secure your information using HTTPS and token-based authentication


  • Integrate multiple web services using resiliency patterns and messaging techniques



Who this book is for



This book is for anyone who wants to learn how to build RESTful web services with the ASP.NET Core framework to improve the scalability and performance of their applications. Basic knowledge of C# and .NET Core will help you make the best use of the code samples included in the book.

Das E-Book können Sie in Legimi-Apps oder einer beliebigen App lesen, die das folgende Format unterstützen:

EPUB

Seitenzahl: 527

Veröffentlichungsjahr: 2019

Bewertungen
0,0
0
0
0
0
0
Mehr Informationen
Mehr Informationen
Legimi prüft nicht, ob Rezensionen von Nutzern stammen, die den betreffenden Titel tatsächlich gekauft oder gelesen/gehört haben. Wir entfernen aber gefälschte Rezensionen.



Hands-On RESTful Web Services with ASP.NET Core 3

 

 

 

 

 

Design production-ready, testable, and flexible RESTful APIs for web applications and microservices

 

 

 

 

 

 

 

 

Samuele Resca

 

 

 

 

 

 

 

 

 

BIRMINGHAM - MUMBAI

Hands-On RESTful Web Services with ASP.NET Core 3

Copyright © 2019 Packt Publishing

All rights reserved. No part of this book may be reproduced, stored in a retrieval system, or transmitted in any form or by any means, without the prior written permission of the publisher, except in the case of brief quotations embedded in critical articles or reviews.

Every effort has been made in the preparation of this book to ensure the accuracy of the information presented. However, the information contained in this book is sold without warranty, either express or implied. Neither the author, nor Packt Publishing or its dealers and distributors, will be held liable for any damages caused or alleged to have been caused directly or indirectly by this book.

Packt Publishing has endeavored to provide trademark information about all of the companies and products mentioned in this book by the appropriate use of capitals. However, Packt Publishing cannot guarantee the accuracy of this information.

 

Commissioning Editor:Richa TripathiAcquisition Editor:Alok DhuriContent Development Editor:Ruvika RaoTechnical Editor:Pradeep SahuCopy Editor: Safis EditingSenior Editor: Rohit SinghProject Coordinator: Francy PuthiryProofreader: Safis EditingIndexer:Pratik ShirodkarProduction Coordinator:Alishon Mendonsa

First published: December 2019

Production reference: 1261219

Published by Packt Publishing Ltd. Livery Place 35 Livery Street Birmingham B3 2PB, UK.

ISBN 978-1-78953-761-1

www.packtpub.com

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
To my family, Francesca, Gabriele, Angelica, Maurizio, Luisa, Guido, and Licia for their sacrifices and for being an example to follow. To my partner, Luisa, for encouraging me in all my choices. To all my friends, for always spreading good vibes.
 

Packt.com

Subscribe to our online digital library for full access to over 7,000 books and videos, as well as industry leading tools to help you plan your personal development and advance your career. For more information, please visit our website.

Why subscribe?

Spend less time learning and more time coding with practical eBooks and Videos from over 4,000 industry professionals

Improve your learning with Skill Plans built especially for you

Get a free eBook or video every month

Fully searchable for easy access to vital information

Copy and paste, print, and bookmark content

Did you know that Packt offers eBook versions of every book published, with PDF and ePub files available? You can upgrade to the eBook version at www.packt.com and as a print book customer, you are entitled to a discount on the eBook copy. Get in touch with us at [email protected] for more details.

At www.packt.com, you can also read a collection of free technical articles, sign up for a range of free newsletters, and receive exclusive discounts and offers on Packt books and eBooks. 

Contributors

About the author

Samuele Resca is a software engineer working at Just Eat and primarily focused on web technologies. He is a Microsoft Most Valuable Professional in Visual Studio and development technologies. Samuele writes software engineering blog posts on Samuele Resca – Blog and The DEV Community, and he contributes to open source projects. He is continuously learning and developing around the web ecosystem with a focus on the .NET Core ecosystem, cloud computing, serverless computing, and reactive programming. Samuele is from Italy, and he currently lives in London.

First, I'd like to thank my whole family, in particular, my mother, Francesca; my dad, Gabriele; and my sister, Angelica, for being a role model to follow, and for welcoming me every time I come back to Italy. To Luisa, for always supporting me unconditionally, in every choice. I'd also like to thank Franco Melandri and Matteo Rizzatti for teaching me a lot and for all the knowledge they have shared with me.

About the reviewer

Ankit Sharma is a software engineer currently working as a senior technical member with ADP in Hyderabad, India. He has over 5 years of extensive experience in Microsoft technologies including C#, ASP.NET, SQL Server, and UI technologies such as jQuery and Angular. He is a technical author and speaker and loves to contribute to the open source community. He writes articles for multiple platforms, which include c-sharpcorner, Dzone, Medium, and TechNet Wiki. For his dedicated contribution to the developer community, he has been recognized as a c-sharpcorner MVP, Dzone MVB, and Top contributor in Technology at Medium. He is also the author of the first ever book on Blazor – Blazor Quick Start Guide. You can tweet him at @ankitsharma_007.

Packt is searching for authors like you

If you're interested in becoming an author for Packt, please visit authors.packtpub.com and apply today. We have worked with thousands of developers and tech professionals, just like you, to help them share their insight with the global tech community. You can make a general application, apply for a specific hot topic that we are recruiting an author for, or submit your own idea.

Table of Contents

Title Page

Copyright and Credits

Hands-On RESTful Web Services with ASP.NET Core 3

Dedication

About Packt

Why subscribe?

Contributors

About the author

About the reviewer

Packt is searching for authors like you

Preface

Who this book is for

What this book covers

To get the most out of this book

Download the example code files

Download the color images

Conventions used

Get in touch

Reviews

Section 1: Getting Started

REST 101 and Getting Started with ASP.NET Core

REST

The importance of being REST compliant

REST requirements

Uniform interface

Manipulation of resources through representations

Self-descriptive messages

Hypermedia as the Engine of Application State

Stateless

Client-server separation

Layered system

Richardson maturity model

Introducing ASP.NET Core

The evolution of ASP.NET

The new .NET ecosystem

.NET STANDARD

Why use ASP.NET Core to build RESTful web services?

Preparing your development environment

.NET Core CLI

IDEs and development tools in ASP.NET Core

Summary

Section 2: Overview of ASP.NET Core

Overview of ASP.NET Core

Setting up our .NET Core project

Overview of .csproj

The Program.cs file in detail

Setting up an ASP.NET Core project

The project structure

The Program.cs and Startup.cs files

Overview of controllers 

Summary

Working with the Middleware Pipeline

Introducing middleware

The middleware pipeline in practice

HttpContext in ASP.NET Core

Class-based middleware

Conditional pipeline

Understanding built-in middleware

Summary

Dependency Injection System

Dependency inversion principle

Benefits of dependency injection

Dependency injection in ASP.NET Core

Registering services using the dependency injection container

Registering services conditionally

Constructor injection

Action method injection

Services life cycle

Transient life cycle

Scoped life cycle

Singleton life cycle

Life cycle madness

Injecting services into middleware

Summary

Web Service Stack in ASP.NET Core

What is a controller?

Identifying controllers

Extending controllers

The ApiController attribute

Handling requests using controllers and actions

Creating an in-memory repository

Handling client requests

Handling HTTP methods using actions

Responding to requests

CreateAt response

Updating resources

Partial updating

Deleting resources

Asynchronous processing and acceptance status

Data transfer objects

Implementing request models

Implementing response models

Implementing validation of requests

Custom validation attributes

Summary

Routing System

Overview of the routing system

Conventional routing

Attribute routing

Custom attribute routing

Routing constraints

Custom constraints

Summary

Filter Pipeline

Introduction to filters

Concrete filter implementations

Asynchronous filters

The scope of filters

The use of filters

Life cycle and dependency injection

Filter use cases

Existing entity constraints

Altering exceptions

Summary

Section 3: Building a Real-World RESTful API

Building the Data Access Layer

Setting up the project

Implementing the domain model

Designing entities

Implement entities

Data access using ORMs

Finding the right tool for the job

Implementing a data access layer using EF Core

Defining the repository pattern and unit of work

Connecting our repository to the database

DbContext definition

Implementing the repository 

Transforming entities into a SQL schema

Custom conversions using the Fluent API

Applying the schema definition on the current data context 

Generating a schema for the Artist and Genre entities

Executing migrations

Defining the configuration part

Testing the EF Core repository

Seeding data using DbContext

Initializing the testing class

Implementing a data access layer using Dapper

Creating stored CRUD procedures

Implementing the IItemRepository interface

Summary

Implementing the Domain Logic

Implementing service classes

The service class interface

Implementing the mapping layer

Mapping logic using Automapper

The service class implementation

Testing the service layer

Refactoring testing classes

Implementing the ItemService tests

Implementing request model validation

Testing request model validation

Dependencies registration

Summary

Implementing the RESTful HTTP Layer

Implementing the item controller

Implementing action methods

Testing controllers using the WebApplicationFactory<T> class

Extending the WebApplicationFactory

Testing a controller

Loading test data using xUnit data attributes

Improving the resilience of the API 

Existence check

JSON-customized errors

Implementing pagination

Exposing related entities 

Extending the data access layer

Extending the test coverage 

Extending the IItemRepository interface

Extending the capabilities of the service layer

Improving the validation mechanism

Updating the dependencies in the Startup class

Adding the related controllers

Extending tests for the ArtistController class

A final overview

Summary

Advanced Concepts of Building an API

Implementing the soft delete procedure

Updating the IItemRepository implementation

Implementing delete operations

Implementing HATEOAS 

Enriching our model with HATEOAS data

Implementing HATEOAS in a controller

The asynchronous code in ASP.NET Core

Task definitions

The need for asynchronous code in ASP.NET Core

What's new in ASP.NET Core?

Best practices in asynchronous programming

Don't use async void methods

Use Task.FromResult over Task.Run

Enable cancellation

Asynchronous code in I/O bound operations

Measure response time using middleware

Summary

The Containerization of Services

An introduction to containers

Docker terminology

Using Docker to run the catalog service

Defining environment variables

Defining the Dockerfile

Executing the docker-compose command

Optimizing Docker images

An overview of different Docker images

Multi-stage builds on the catalog service

Summary

Service Ecosystem Patterns

An introduction to the cart service

The theory behind the mediator pattern

The domain model and the data access layer

The ICartRepository Redis implementation

Handlers and routes implementation

Exposing functionalities using CartController

Implementing resilient communication using an HTTP client

Implementing the catalog HTTP client 

Integrating an HTTP client into the cart service

Implementing resilience using Polly.NET

Integrating Polly into ICatalogService

Sharing events using an event bus

Setting up a RabbitMQ instance and publishing an event

Running the cart service using Docker

Summary

Implementing Worker Services Using .NET Core

Introducing worker services

Understanding the worker services life cycle

Hosting models

Implementing a health-checking worker

Project structure overview

Running a worker service on Docker

Consuming the sold-out event

Creating a sold-out handler

Testing the sold-out process

Configuring the background service

Summary

Securing Your Service

Overview of secure communication

Securing data using HTTPS  

Enforcing HTTPS in ASP.NET Core

HTTP/2 on Kestrel

Enabling CORS in ASP.NET Core

Implementing CORS using the middleware approach

Implementing CORS using the attribute approach

Securing APIs with token-based authentication

Implementing token-based authentication

Defining the service layer

Applying authentication on the controller

Storing data using EF Core

Declaring the identity database context

Testing authentication

Summary

Section 4: Advanced Concepts for Building Services

Caching Web Service Responses

Introduction to the HTTP caching system

The HTTP caching specification

Implementing response caching in ASP.NET Core

Implementing a distributed cache

Implementing the IDistributedCache interface

Inject memory cache into the tests

Summary

Logging and Health Checking

Logging in ASP.NET Core

The key characteristics of logging

Implementing the logging part

Exception logging

Verifying logging using Moq

Implementing logging providers

Implementing a custom log provider in tests

Web service health check 

Implementing health checks on databases

Implementing custom health checks

Summary

Deploying Services on Azure

Getting started with Azure

Pushing containers into Azure Container Registry

Creating an Azure Container Registry

Configuring Azure Container Instances

Configuring app services

Creating an app service using a container image

Summary

Documenting Your API Using Swagger

Understanding OpenAPI

Implementing the Swagger project

Implementing OpenAPI in ASP.NET Core services

Understanding ASP.NET Core's conventions

Custom conventions

Summary

Testing Services Using Postman

Overview of Postman

Testing the API using Postman

Using the runner to test the APIs

Importing a collection using OpenAPI

Summary

Other Books You May Enjoy

Leave a review - let other readers know what you think

Preface

.NET Core is a breath of fresh air for all the consumers of the Microsoft ecosystem. The old ASP.NET and .NET framework both have a long history. Over the years, the growth of the .NET framework and the long-time support constraints have resulted in odd implementations and hard-to-maintain web applications and web services.

Furthermore, the strong dependency between .NET framework and the Windows OS has led to substantial limitations in the cloud technology world. 

.NET Core and ASP.NET Core are designed to evolve. They use abstract software development practices including open source, community-oriented approaches, as well as continuous improvement concepts. Today, ASP.NET Core is more flexible, fast, and powerful than ever. All the constraints developers had faced with .NET framework have been expelled and rewritten from scratch. Consequently, it is now possible to run .NET Core on every platform with no limitations. The framework is directly shipped with the .NET Core application. Therefore, it is possible to run it using a containerization approach. The documentation, the issues, and the roadmap are all available on GitHub.  Microsoft is now following, by default, an open source way of working. 

I've been interested in .NET Core since the first release of the old DNX runtime. This book will introduce you to the power of ASP.NET Core and how to use its strength and flexibility to run web services. Furthermore, the book aims to fight the prejudices that people have regarding the .NET ecosystem and seeks to increase the adoption of .NET Core.

Who this book is for

This book is intended for those who want to learn how to build RESTful web services with ASP.NET Core. To make the best use of the code samples included in the book, you should have basic knowledge of C#.

What this book covers

Chapter 1, REST 101 and Getting Started with ASP.NET Core, explains some fundamentals of RESTful APIs and how they can be useful when building an application.

Chapter 2, Overview of ASP.NET Core, shows the essential components of the .csproj file. It illustrates the main components of a project: the Startup class and theProgram.csfile. 

Chapter 3, Working with the Middleware Pipeline, explores middlewares, which are a central part of ASP.NET Core. This chapter walks you through the middleware pipeline and explains how it can handle requests and initialize different services based on them. Furthermore, the chapter covers the different out-of-the-box middlewares provided by ASP.NET Core and how to build a custom middleware.

Chapter 4, Dependency Injection System, introduces you to dependency injection principles and to the concepts behind dependency injection. It shows you how to use dependency injection to initialize components and options inside your application and how to use them inside your controllers.

Chapter 5, Web Service Stack in ASP.NET Core, describes how to create a web service stack in ASP.NET Core. It goes into depth on concerns such as controllers, action methods, action results, model binding, and model validation.

Chapter 6, Routing System, delves into the routing system, which handles HTTP requests. The chapter shows you how to deal with the default routing system of ASP.NET Core.

Chapter 7, Filter Pipeline, covers another essential topic in ASP.NET Core: filters. Filters are a vital component for achieving cross-cutting implementations in our services. The chapter introduces them; it shows how to implement our filters and explores some concrete use cases.

Chapter 8, Building the Data Access Layer, introduces the domain model part. The main topics are related to how to build the domain model and how to access data using object-relational mapping (ORM).

Chapter 9, Implementing the DomainLogic, describes the mediator pattern approach to keeping logic isolated from other application components. The mediator pattern is one way to handle and manage our logic. 

Chapter 10, Implementing the RESTful HTTP Layer, explains how to retrieve data from the mediator and use it inside our controllers. 

Chapter 11, Advanced Concepts of Building the API, presents some advanced concepts around building APIs in ASP.NET Core. The chapter will cover topics around the soft deletion of resources, and it introduces some good practices for working with asynchronous code in ASP.NET Core.

Chapter 12, The Containerization of Services, gives you a quick introduction to containers and how they can be useful when running your application locally in a sandboxed environment. 

Chapter 13, Service Ecosystem Patterns, focuses on the patterns involved when multiple services are part of the same ecosystem.

Chapter 14, Implementing Worker Services Using .NET Core, is dedicated to the new worker template of .NET Core. Workers provide a way to implement small services or daemons that can be used to perform background operations.

Chapter 15, Securing Your Service, talks about securing a service or an API. Besides that, it covers concepts including Secure Sockets Layer (SSL), Cross-Origin Resource Sharing (CORS), and authentication.

Chapter 16, Caching Web Service Responses, covers all the caching choices provided by ASP.NET Core.

Chapter 17, Logging, Monitoring, and Health Checking, shows some best practices for logging and monitoring your application.

Chapter 18, Deploying Services on Azure, shows some examples of how to host a web service in the cloud.

Chapter 19, Documenting Your API Using Swagger, introduces you to the OpenAPI standard and how to implement it in an ASP.NET Core application.

Chapter 20, Testing Services Using Postman, shows how to use Postman to test a web service.

To get the most out of this book

This book assumes that you have some knowledge of C# (or a similar object-oriented programming language, such as Java) and that you have some experience in building web applications.

This book doesn't require any specific tools, but you will need .NET Core installed on your machine (https://dotnet.microsoft.com/download). I strongly suggest that you have at least one code editor, such as Visual Studio Code, possibly with OmniSharp, or an integrated development environment (IDE) such as Visual Studio (on Windows or Mac), or Rider IDE (on Windows, Mac, or Linux).

I've written all the examples on macOS X using Rider IDE and Bash.

Download the example code files

You can download the example code files for this book from your account at www.packt.com. If you purchased this book elsewhere, you can visit www.packt.com/support and register to have the files emailed directly to you.

You can download the code files by following these steps:

Log in or register at

www.packt.com

.

Select the

SUPPORT

tab.

Click on

Code Downloads & Errata

.

Enter the name of the book in the

Search

box and follow the onscreen instructions.

Once the file is downloaded, please make sure that you unzip or extract the folder using the latest version of:

WinRAR/7-Zip for Windows

Zipeg/iZip/UnRarX for Mac

7-Zip/PeaZip for Linux

The code bundle for the book is also hosted on GitHub at https://github.com/PacktPublishing/Hands-On-RESTful-Web-Services-with-ASP.NET-Core-3. In case there's an update to the code, it will be updated on the existing GitHub repository.

We also have other code bundles from our rich catalog of books and videos available at https://github.com/PacktPublishing/. Check them out!

Download the color images

We also provide a PDF file that has color images of the screenshots/diagrams used in this book. You can download it here: https://static.packt-cdn.com/downloads/9781789537611_ColorImages.pdf.

Conventions used

There are a number of text conventions used throughout this book.

CodeInText: Indicates code words in text, database table names, folder names, filenames, file extensions, pathnames, dummy URLs, user input, and Twitter handles. Here is an example: "The headers part tells the client that the response should be processed using a specific content-type; in this case, application/json."

A block of code is set as follows:

<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType>

<TargetFrameworks>netcoreapp3.0;net461</TargetFrameworks>

</PropertyGroup></Project>

When we wish to draw your attention to a particular part of a code block, the relevant lines or items are set in bold:

<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType>

<TargetFrameworks>netcoreapp3.0;net461</TargetFrameworks>

</PropertyGroup></Project>

Any command-line input or output is written as follows:

dotnet build

dotnet run

Bold: Indicates a new term, an important word, or words that you see onscreen. For example, words in menus or dialog boxes appear in the text like this. Here is an example: "As you can see, it is running Hello, World!"

Warnings or important notes appear like this.
Tips and tricks appear like this.

Get in touch

Feedback from our readers is always welcome.

General feedback: If you have questions about any aspect of this book, mention the book title in the subject of your message and email us at [email protected].

Errata: Although we have taken every care to ensure the accuracy of our content, mistakes do happen. If you have found a mistake in this book, we would be grateful if you would report this to us. Please visit www.packt.com/submit-errata, selecting your book, clicking on the Errata Submission Form link, and entering the details.

Piracy: If you come across any illegal copies of our works in any form on the Internet, we would be grateful if you would provide us with the location address or website name. Please contact us at [email protected] with a link to the material.

If you are interested in becoming an author: If there is a topic that you have expertise in and you are interested in either writing or contributing to a book, please visit authors.packtpub.com.

Reviews

Please leave a review. Once you have read and used this book, why not leave a review on the site that you purchased it from? Potential readers can then see and use your unbiased opinion to make purchase decisions, we at Packt can understand what you think about our products, and our authors can see your feedback on their book. Thank you!

For more information about Packt, please visit packt.com.

Section 1: Getting Started

In this section, we will introduce you to all the macro concepts of REST APIs and ASP.NET Core. You will also learn about local development.

This section includes the following chapter:

Chapter 1

,

REST 101 and Getting Started with ASP.NET Core

REST 101 and Getting Started with ASP.NET Core

Nowadays, almost all applications rely on web services. A lot of them operate using the RESTful method. The resource-centric approach and the simplicity of the REST style have become an industry standard. Therefore, it is essential to understand the theory behind the REST way of working and why it is important. This chapter will introduce you to the Representational State Transfer (REST) method. We will see what the definition of REST is and how to identify REST-compliant web services. We will also introduce .NET Core 3.1 and ASP.NET Core, the brand new version of the open-source, cross-platform framework provided by Microsoft.

In summary, this chapter covers the following topics:

Overview of REST architectural elements

A brief introduction to the .NET ecosystem

Why you should choose .NET to build a RESTful web service

By the end of this chapter, you will have an overview of some useful tools and IDEs that you can use to start developing on .NET Core.

This chapter will cover some of the base concepts of .NET Core 3.1 and ASP.NET Core. You need to have either Windows, Linux, or macOS installed. The setup process will depend on which OS you are using. We'll look at the different tools that can be used to develop apps and web services in .NET Core. 

REST

What is REST?  Representational State Transfer (REST) is usually defined as a software architecture style that applies some constraints to a web service. It identifies a set of resource-centric rules that describe the roles and the interaction between the constraints of a distributed hypermedia system, instead of focusing on the implementation of the components. Although it is quite rare to find a REST service that does not use HTTP, the definition does not mention any of these topics and instead describes REST as media- and protocol-agnostic.

The preceding definition can be further explained with an example. Consider an e-commerce website. When you browse a list of products and click on one them, the browser interprets your click as a request to a specific resource; in this case, the details of the product you clicked on. The browser makes an HTTP call to the URI, which corresponds to the details of the product and asks for a specific resource using the URI. This process is shown in the following diagram:

The concept of REST is pretty similar: the client asks the server for a specific resource, and this allows them to navigate and obtain other information about resources stored on the server.

The importance of being REST compliant

Before we discuss REST, we should understand the importance of web services in the modern application development world.

A typical modern application uses web services to obtain and query data. Any company that develop any product or solution uses web services to deliver and track information. This is because it can be difficult to replicate all the data and every behavior you need for every client who uses your application. Web services are also useful for providing access to third-party clients and services. Consider, for example, the Application Programming Interfaces (APIs) of Google Maps or Instagram: these platforms expose information through HTTP to share it with other companies and services.

The REST approach to web service architecture became increasingly popular because it is straightforward and clear. Unlike some old methods, such as the Simple Object Access Protocol (SOAP) or the Windows Communication Foundation (WCF), REST services provide a clean way of querying data. Different information can be obtained using different URIs without the need for adding any overhead to requests. 

Today, more than ever, our services need to be prepared to scale so that they can be adapted to consumers. In a world of different technologies and distributed teams around the globe, we should be able to transform our architecture to solve complex business challenges. HTTP and REST help us address these challenges.

REST requirements

Roy Thomas Fielding is the main person behind the formalization of the HTTP protocol and the REST style: he described them in his dissertation, Architectural Styles and the Design of Network-based Software Architectures (https://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm). Moreover, Fielding's dissertation clearly defines the constraints of a REST system, as follows:

Uniform interface

Stateless

Cacheable

Client-server

Layered system

Code on demand

All of these, apart from code on demand, are essential when we wish to define a web service as REST-compliant. To explain these concepts, we will use the APIs provided by The New York Times: https://developer.nytimes.com/. To use these APIs, you need to go through a pre-authentication process. You can get an API key for this from the following link: https://developer.nytimes.com/signup. 

Uniform interface

Uniform interface refers to the separation between the client and the server. This is advantageous because it means that the two systems are independent. The first principle of a uniform interface is that it should be resource-based, which means that we should start to think in a resource-oriented way. Therefore, every object or entity inside our system is a resource and a URI uniquely identifies each of them. Furthermore, if we think about the HTTP protocol, each resource is presented to the client in the form of XML or JSON to decouple the client from the server.

Let's use The New York Times APIs to understand this topic. Consider the following URI:

http://api.nytimes.com/svc/archive/v1/2018/6.json?api-key={your_api_key}

It contains some precise information about the resources we are asking for, including the following: 

The fact that we are getting information from the

archive

 section of the newspaper data

The specific month we are asking for; in this case, June 2018

The fact that the resource will be serialized using

JSON format

Manipulation of resources through representations

Let's take another API request provided by The New York Times:

https://api.nytimes.com/svc/books/v3/lists.json?api-key={your_api_key}&list=hardcover-fiction

This provides a list of books based on a category; in this case, this category is Hardcover Fiction. Let's analyze the response:

{ "status": "OK", "copyright": "Copyright (c) 2018 The New York Times Company. All Rights Reserved.", "num_results": 15, "last_modified": "2018-06-28T02:38:01-04:00", "results": [ { "list_name": "Hardcover Fiction", "display_name": "Hardcover Fiction", "published_date": "2018-07-08", "isbns": [ { "isbn10": "1780898401", "isbn13": "9780316412698" } ], "book_details": [ { "title": "THE PRESIDENT IS MISSING", "contributor": "by Bill Clinton and James Patterson", "author": "Bill Clinton and James Patterson", "contributor_note": "", "price": 0, "age_group": "", "publisher": "Little, Brown and Knopf" } ], "reviews": [ { "book_review_link": "", "first_chapter_link": "" } ] } .... ]}

As you can see, this is a clear representation of the resource. The client has all the required information to process and modify data using APIs (if the APIs allow that). 

Self-descriptive messages

Let's look at the response of the following call:

https://api.nytimes.com/svc/books/v3/lists.json?api-key={your_api_key}&list=hardcover-fiction

As we mentioned previously, the response is a representation of the data, either stored in a data source or obtained from another system. In any case, some information is missing: how does the client know the format of the response? This kind of information is usually written in the response header. For example, here are all the headers of the previous request:

accept-ranges: bytesaccess-control-allow-headers:

Accept, Content-Type, X-Forwarded-For, X-Prototype-Version, X-Requested-With

access-control-allow-methods: GET, OPTIONSaccess-control-allow-origin: *access-control-expose-headers: Content-Length, X-JSONage: 0connection: keep-alivecontent-length: 14384content-type: application/json; charset=UTF-8date: Tue, 03 Jul 2018 12:47:08 GMTserver: Apache/2.2.15 (CentOS)vary: Originvia: kong/0.9.5x-cache: MISSx-kong-proxy-latency: 4x-kong-upstream-latency: 29x-ratelimit-limit-day: 1000x-ratelimit-limit-second: 5x-ratelimit-remaining-day: 988x-ratelimit-remaining-second: 4x-varnish: 63737329

The headers part tells the client that the response should be processed using a specific content-type; in this case, application/json. It also provides information about encoding, caching, and related meta information, such as the age header, which contains the time in seconds that the object has been in the proxy cache.

Hypermedia as the Engine of Application State

Services usually deliver a state to clients via body content, response codes, and response headers. Above all, hypermedia-driven services (HATEOAS) include the URI of other resources within their responses. The following example describes the concept of HATEOAS:

{ "links": { "self": { "href": "http://example.com/people" }, "item": [ { "href": "http://example.com/people/1", "title": "Kendrick West" }, { "href": "http://example.com/people/2", "title": "Anderson Rocky" } ] },}

The previous response provides a list of people, together with the URIs that specify detailed information of each person. Therefore, the client knows the right URI of the request to use in order to get the information regarding each resource.

Stateless

Being stateless is a crucial characteristic of a REST service. Indeed, HTTP, as a stateless protocol, doesn't keep track of all the information about the connection between the client and the server once the communication ends.  

A stateless protocol forces the client to fulfill the request with all the required information each time it needs some information from the server. Let's take one of the previous URIs:

https://api.nytimes.com/svc/books/v3/lists.json?api-key={your_api_key}&list=hardcover-fiction

The client has to send the API key with each request to be authenticated by the server. Furthermore, it must store the API key information.

Statelessness is very important if we wish to take advantage of REST services. Nowadays, with the rise of highly distributed systems, it is difficult to deal with stateful services because this requires the states to be managed and replicated on different servers. A stateless approach helps delegate state management to the client. 

Client-server separation

The main aim of REST services is to decouple the server and the client. This is very important because it helps keep unique business logic and data storage for each client application. Applications are usually distributed across a multitude of different clients, including the web, smartphones, smart TVs, and the IoT. A REST approach helps us prevent logic replication across clients. This means that the client does not have any business logic or storage, and the server does not deal with user interfaces or the presentation layer.

Layered system

The concept of a layered system is strictly related to the structure of the infrastructure of our application. RESTful services allow a loosely coupled approach because the information is transferred over a protocol – in most cases, HTTP – and each server has a single high-level purpose. Proxy servers, web servers, and database servers are usually isolated and they cover a purpose in our feature, if you have one server that provides all the required features, it is often hard to maintain and scale.

Richardson maturity model

The Richardson maturity model is a model that was developed by Leonard Richardson, and its purpose is to measure the maturity of APIs by providing some general criteria. The model has four classification steps, from Level 0 to Level 3. The highest level corresponds to a more compliant service. This model isn't just for theoretical purposes; it also helps us understand some of the recommended methods for web service development. Let's take a look at an overview of these different levels. The following diagram shows the structure of the levels in the Richardson maturity model:

A generic service is at Level 0: The Swamp of Plain Old XML when it uses a generic protocol superficially (in the case of web services, this is HTTP). An example of this is a heavy SOAP web service. SOAP implementations use only one URI and only one HTTP verb, and they wrap each request message within a massive envelope.

As we mentioned previously, thinking in terms of resources is the best way to understand and design an API. Therefore, a generic service that's at Level 1 uses multiple URIs associated with different resources. For example, if we think about an API of a general store, we could obtain the complete list of product categories by calling this sample URI:

GET https://api.mystore.com/v1/categories

At the same time, we can get the details of a single category by calling the following URI:

GET https://api.mystore.com/v1/categories/{category_id}

On the other hand, we can get a list of products related to a single category by calling the following URI:

GET https://api.mystore.com/v1/categories/{category_id}/products

As you can see, we can obtain different information by calling different URIs. There is no envelop, and all the requested information is contained in the URI. 

Level 2, which is related to HTTP verbs, introduces the use of HTTP verbs to enhance the information that's transferred on request. Let's take the previous request URI as an example:

https://api.mystore.com/v1/categories/{category_id}/products

This can produce different results, depending on the HTTP verb. The following table shows the meanings of various HTTP verbs:

HTTP verbs
Performed operations
Example
GET
Retrieves information about a resource

GET /v1/categories/ HTTP/1.1Host: api.mystore.comContent-Type: application/json

POST
Creates a new item related to the resource

POST /v1/categories/ HTTP/1.1Host: api.mystore.comContent-Type: application/json{ "categoryId": 1, "categoryDescription": "Vegetables"}

PUT
Replaces an item related to the resource

PUT /v1/categories/1 HTTP/1.1Host: api.mystore.comContent-Type: application/json{ "categoryId": 1, "categoryDescription": "Fruits and Vegetables"}

PATCH
Updates an item related to the resource

PUT /v1/categories/1 HTTP/1.1Host: api.mystore.comContent-Type: application/json{ "categoryDescription": "Fruits and Vegetables"}

DELETE
Deletes an item related to the resource

DELETE /v1/categories/1 HTTP/1.1Host: api.mystore.comContent-Type: application/json

 

Different HTTP verbs correspond to various data operations. As opposed to a Level 0 service, which doesn't use any specifications of HTTP to deliver information, a Level 2 service takes advantage of HTTP specifications to deliver as much information as possible. Finally, a system with a Level 3 service implements the concept of HATEOAS. As we discussed in the previous section, a HATEOAS provides the resource's URI inside its response. A clear advantage of this approach is that the client doesn't need any information on its side to navigate through the web service's resources. Most importantly, if our web service adds the resource's URI, the client immediately has all the information they need.

Introducing ASP.NET Core

At the time of writing this book, .NET Core 3.1 is the LTS (short for Long Term Support) version of the framework powered by Microsoft and the community. ASP.NET Core is the highly modular web framework that runs over the .NET Core platform: it can be used to develop a wide range of web solutions, such as web applications, web assembly client applications and web API projects.

To learn about some of the basic concepts of ASP.NET Core, we need to understand the Model View Controller (MVC) pattern that is implemented in ASP.NET Core. 

MVC separates our web application by grouping implementations into three different areas. In a web environment, the starting point is usually a web request that's made by a client or a generic user. The request passes through a middleware pipeline, and the controller then handles it. The controllers also perform some logic operations and populate our model.

The model is the representation of the state of the application. When it is associated with a view, it is called a view model. Once the model is populated, the controller returns a specific view, depending on the request. The purpose of the views is to present data through HTML pages.

In the case of a web API stack, which is the typical way of building web services in ASP.NET Core, the process is the same except for the view part. Instead of this, the controller serializes the model in the response.

To understand how ASP.NET Core helps developers build web services, let's go through the history of the ASP.NET framework.

The evolution of ASP.NET

The first version of ASP.NET was released in 2002 when Microsoft decided to invest in web development. They released ASP.NET Web Forms, which is a set of UI components that we can use to build web interfaces. The core idea of this approach was to provide a very high-level abstraction tool that can produce a GUI for the web. Providing this level of abstraction was a good idea because developers were not familiar with the web. However, ASP.NET Web Forms came with a lot of downsides. First of all, developers had limited control over HTML, and components had to store information in a view state, which was transferred and updated between the client and the server. Furthermore, the components were not correctly separated, and developers tended to mix the presentation code with the business logic code.

In order to improve the experience of developing web applications, Microsoft announced the arrival of ASP.NET MVC in 2007. This new development platform ran on the ASP.NET framework and used concepts from other development platforms that implemented MVC patterns, such as Ruby on Rails. The ASP.NET MVC framework still had some points of weakness. It was built on ASP.NET, which means it had to maintain its retro compatibility with old web forms and web services frameworks such as WCF. Furthermore, it only ran on Windows servers combined with Internet Information Services (IIS).

The latest web framework to be developed by Microsoft is ASP.NET Core. It runs on .NET Core, which is cross-platform and open source. With ASP.NET Core, Microsoft made the choice to release a new lightweight framework that does not have any back-compatibility components derived from previous versions of ASP.NET.  

The new .NET ecosystem

Let's look at an overview of the .NET ecosystem to understand the different frameworks that act as the foundations of ASP.NET Core. Some of the information provided here may sound obvious, but it is essential to clarify the differences between different runtimes and frameworks:

The first block is related to Desktop Packs, which provides the tools for the development of desktop applications starting from .NET Core 3.0. We will not use these tools in this book since they are strictly related to desktop development.

The second block is related to the cross-platform part of .NET Core. This set of tools allows developers to build applications on the WEB, DATA, and AI/ML domain. The WEB section refers to ASP.NET Core, which is a collection of libraries that comes with .NET Core. Usually, ASP.NET Core is combined with the DATA access part. Later in this book, we will see how we can use EF Core to access the database layer. Finally, the AI/ML section, which will not be discussed in this book, provides useful tools in the machine learning domain. At the bottom of the preceding diagram, we have a common layer, that is, .NET STANDARD. It allows developers to build third-party libraries that can be used by the Desktop Packs and by the WEB, DATA, and AI/ML parts.

In conclusion, the new .NET ecosystem can be used by any developer, including cloud developers, web developers, and desktop developers. As we mentioned previously, it also runs anywhere and on any platform. In this book, all of our examples will be based on .NET Core.

.NET STANDARD

.NET STANDARD was introduced along with .NET Core. The aim of the .NET STANDARD is to provide a common API surface for .NET Core and .NET Framework. It works as a unique Base Class Library (BCL) for our applications in both .NET Framework and .NET Core. The release of .NET Standard 2.0 has introduced 32,000 compatible APIs and supports the following framework versions:

.

NET Framework 4.6.1 +

.NET Core 2.0 +

Mono 5.4 +

Recently, Microsoft introduced .NET Standard 2.1. This new version provides new APIs that were introduced as part of the open-source development of .NET Core 3.0.  .NET Standard 2.1 will be the common point between the new versions of .NET Core, starting from the 3.0 version, and the other versions of the upcoming frameworks, such as Mono.

You may wish to choose the .NET Standard for different reasons:

To build third-party libraries that are compatible with both .NET Core and .NET Framework. In that case, your package will target .NET Standard 2.0. Eventually, if you want to use the newly optimized APIs that we described previously, it is possible to use multi-targeting to target both .NET Standard 2.0 and .NET Standard 2.1.

To migrate your .NET Framework codebase gradually by isolating logic on .NET Standard projects.

For example, consider a class library project which is used by different versions of .NET. The library may run on either .NET Core or .NET Framework. To avoid maintainability pitfalls, the library package can be compiled for multiple versions of .NET Standard and it can be used by both a .NET Core and a .NET Framework solution. 

Why use ASP.NET Core to build RESTful web services?

There is a massive choice of web frameworks that allow developers to build REST web services. One such framework is ASP.NET Core on .NET Core 3.1.  .NET Core 3.1 provides a new, lightweight, cross-platform and opensource way to build web applications. Most importantly, it is designed to be cloud-ready: the framework is no longer part of the server, unlike in .NET Framework; instead, it is shipped with the application.

Another key point is that .NET Core maintains a high level of modularity, which adheres to the Unix philosophy and allows you to use only what you need in tailored applications. ASP.NET Core also introduces two new hosting solutions for web applications and web services:

Kestrel

: T

he default HTTP server for ASP.NET Core. It supports HTTPS and web sockets, and it runs on Windows, Linux, and macOS. 

Kestrel

 is usually combined with a 

reverse-proxy, 

such as NGINX, IIS, or Apache.

HTTP.sys

: A

 Windows-only HTTP server that can be used as an alternative to Kestrel on Windows.

ASP.NET Core and .NET Core are developed by Microsoft and the community, and they are open source projects. In the case of ASP.NET Core, open source isn't just a buzzword; all the features are community-driven, and the ASP.NET team streams a community standup video on YouTube every week, in which they discuss roadmaps, deadlines, and issues. All the .NET Core code is available on GitHub at the following links:

.NET Core

: The repository of .NET Core (

https://github.com/dotnet/core

)

ASP.NET Core

: Contains all the references to ASP.NET Core projects (

https://github.com/aspnet/AspNetCore

)

All the repositories usually come with a roadmap and some contributing guidelines. It is possible to open issues and contribute to the code base. Microsoft has also founded the .NET foundation, an independent organization that fosters open development and collaboration around the .NET ecosystem.

The ASP.NET Core team is also focused on the performance of the framework. All the benchmark results are available on GitHub: https://github.com/aspnet/benchmarks.

Preparing your development environment

In this section, we will show you how to set up your development environment so that you can develop web services using ASP.NET Core. As we mentioned previously, .NET Core is cross-platform, so it can run on the most common OSes. We will also look at how to interact with the .NET Core CLI, which is the starting point for building, running, developing, and testing our services. 

First of all, let's start by downloading .NET Core 3.1 from https://www.microsoft.com/net/download/. In our case, we'll install the SDK version, which contains all the components that are required for our development environment, including ASP.NET Core.

.NET Core CLI

Unlike the .NET framework, .NET Core provides an easy to use CLI that exposes all the necessary functionalities we can use to build applications and services. Once .NET Core is installed on your machine, run the dotnet --help command. You will see the following result:

.NET Core SDK (3.1.100)Usage: dotnet [runtime-options] [path-to-application] [arguments]Execute a .NET Core application.runtime-options: --additionalprobingpath <path> Path containing probing policy and assemblies to probe for. --additional-deps <path> Path to additional deps.json file. --fx-version <version> Version of the installed Shared Framework to use to run the application. --roll-forward <setting> Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable).path-to-application: The path to an application .dll file to execute.Usage: dotnet [sdk-options] [command] [command-options] [arguments]Execute a .NET Core SDK command.sdk-options: -d|--diagnostics Enable diagnostic output. -h|--help Show command line help. --info Display .NET Core information. --list-runtimes Display the installed runtimes. --list-sdks Display the installed SDKs. --version Display .NET Core SDK version in use.SDK commands: add Add a package or reference to a .NET project. build Build a .NET project. build-server Interact with servers started by a build. clean Clean build outputs of a .NET project. help Show command line help. list List project references of a .NET project. migrate Migrate a project.json project to an MSBuild project. msbuild Run Microsoft Build Engine (MSBuild) commands. new Create a new .NET project or file. nuget Provides additional NuGet commands. pack Create a NuGet package. publish Publish a .NET project for deployment. remove Remove a package or reference from a .NET project. restore Restore dependencies specified in a .NET project. run Build and run a .NET project output. sln Modify Visual Studio solution files. store Store the specified assemblies in the runtime package store. test Run unit tests using the test runner specified in a .NET project. tool Install or manage tools that extend the .NET experience. vstest Run Microsoft Test Engine (VSTest) commands.Additional commands from bundled tools: dev-certs Create and manage development certificates. fsi Start F# Interactive / execute F# scripts. sql-cache SQL Server cache command-line tools. user-secrets Manage development user secrets. watch Start a file watcher that runs a command when files change.Run 'dotnet [command] --help' for more information on a command.

The first thing to notice is the version of .NET Core, which is the version of .NET Core, that is, .NET Core SDK (3.1.100), followed by a list of Software Development Kit (SDK) commands. This contains the commands that are commonly executed during the development stage, such as dotnet build, dotnet restore, and dotnet run. These are used to build our projects, restore the NuGet dependencies, and run our project, respectively. Another relevant section is additional tools, which contain all the third-party CLI packages we will require, such as EF Core. In fact, the .NET Core CLI allows you to extend its functionality by adding specific tools in the form of NuGet packages.

IDEs and development tools in ASP.NET Core

.NET Core CLI is a base upon which higher-level tools such as IDEs, code editors, and continuous integration (CI) tools can be placed. Even though .NET Core is a cross-platform framework, there are various tools that can be used to build web applications and services on different platforms. The following table provides a recap of the different IDEs and editors that can be used to build ASP.NET Core:

Softwares

Windows
Linux
macOS X
Visual Studio 2019 (Community, Pro, and Enterprise)
Supported
-
-
Visual Studio Code and OmniSharp
Supported
Supported
Supported
Rider 
Supported 
Supported
Supported
Visual Studio for Mac 
-
-
Supported

 

As you can see, it is possible to use different IDEs and code editors for different platforms. The choice you make usually depends on different factors. Let's look at an overview of the different editors:

Visual Studio 2019 (Community, Pro, and Enterprise)

: An editor that is well-known to anyone who has already developed on the .NET ecosystem. The community version of this product is totally free, and you can find it at 

https://visualstudio.microsoft.com/it/downloads/

.

 

Visual Studio 2019 is the most comfortable choice if you wish to start building on Windows.

Visual Studio Code and OmniSharp

: A popular and open source editor powered by Microsoft and the community. It is cross-platform and built on Electron. OmniSharp is a useful third-party package for Visual Studio Code and other code editors that provides some integration with .NET Core projects. It also provides an IntelliSense feature.

Rider

: A brand new IDE powered by JetBrains and based on the IntelliJ platform and ReSharper. It is compatible with every platform, but it is not free. I've tried it in large projects, and it works well, primarily to provide the ReSharper integration out of the box.

Visual Studio for Mac

: A new IDE powered by Microsoft. It is only compatible with macOS and provides a few functionalities we can use to write C# or F# code in the .NET Core ecosystem. This IDE is still at an early stage, but it has a lot of advanced features.

In conclusion, tools such as Visual Studio 2019, Rider, and Visual Studio for Mac provide a great experience when combined with .NET Core. On the other hand, Visual Studio Code is the lightest and fastest editor. In the upcoming chapters and code demonstrations, I will use the .NET Core CLI to reproduce the same steps in different operating systems.

Summary

In this chapter, we have taken an overview of the REST style by considering some concrete some concrete examples. We also learned about some of the basic concepts of the .NET ecosystem, including how it is structured and why ASP.NET Core is an excellent choice if we wish to build web services. We also looked at an overview of the .NET Core CLI and the IDEs and code editors related to the .NET ecosystem.

The topics we covered in this chapter provide a good understanding of what REST means and why is important to follow this kind of principle when we develop a web service. Furthermore, we also looked at the fundamentals for setting up .NET Core in our local environment.

The next chapter will focus on ASP.NET Core and ASP.NET Core MVC. You'll learn how to set up a project using the .NET CLI and explore some of the fundamentals concepts of ASP.NET Core.  

Section 2: Overview of ASP.NET Core

In this section, you will learn about the ins and outs of ASP.NET Core and be provided with an overview of the key components of the ASP.NET Core application.

This section includes the following chapters:

Chapter 2

,

Overview of ASP.NET Core

Chapter 3

,

Working with the Middleware Pipeline

Chapter 4

,

Dependency Injection System

Chapter 5

,

Web Service Stack in ASP.NET Core

Chapter 6

,

Routing System

Chapter 7

,

Filter Pipeline

Overview of ASP.NET Core

 In this chapter, we will explore some of the fundamental concepts of ASP.NET Core. .NET Core is cross-platform, but the IDEs and code editors that are used with it might vary depending on which OS they run on. To avoid repetition and cover all OS variants, I always use the CLI in the examples presented in this book. Furthermore, the dotnet instruction is the unique entry point and is also used, under the hood, by code editors and IDEs.

This chapter will cover the following topics:

Setting up a .NET Core 3.1 and ASP.NET Core project

The file structure of a .NET Core project template

Setting up our .NET Core project

This chapter assumes that you have already installed .NET Core version 3.1 or higher on your machine. First of all, let's start by launching the following command in our console:

dotnet new

The output will appear as follows:

The result of the dotnet new instruction

The preceding output shows all the .NET Core project templates available on the local machine. Each of these has a user-friendly name, a short name, and tags. They are available in C#,  F# and VB; the default is C#.

To create a new template, we'll use the short name. For example, in order to create a console application, we should run the following instruction:

dotnet new console -n HelloWorld

The preceding instruction will create a new project in the current folder, with the following tree structure:

.├── HelloWorld.csproj├── Program.cs└── obj ├── ...

The HelloWorld.csproj file contains all the meta-information about the project. The .NET Core version of the .csproj file is more lightweight compared to the .csproj file in previous versions of the .NET Framework. We'll discuss the new structure of this project file next in this chapter. The Program.cs file is the entry point of the application. 

To build and execute our project, we can run the following commands inside the project folder:

dotnet build

dotnet run

As expected, we obtain the following result:

Hello World!

Unlike old .NET Framework projects, the build and run steps are lightweight processes, and they don't require any additional tools or configurations. In fact, .NET Core is not strictly chained to the development machine like the .NET Framework. Eventually, developers can write code without any other IDEs or code editors. However, for obvious reasons, it is always recommended that you use them to simplify the development process.

It is also essential to note that, once we execute the dotnet build command, the project files will change in the following way:

.├── HelloWorld.csproj├── Program.cs├── bin│ └── Debug│ └── netcoreapp3.1│ ├── ...└── obj├── Debug│ └── netcoreapp3.1│ ├── ...

The bin/Debug/ folder contains all the app's DLLs. Below that, we can see the netcoreapp3.1 folder, which refers to the current target framework. Therefore, if you build your project using a multi-target approach, you will find a folder for each target framework you specified. Now that we are able to run a simple console app, let's have a closer look at the csproj present in the project.