Giter Club home page Giter Club logo

netcore-webapi-starter's Introduction

.NET Core Web API Starter Template

Table of contents

General info

This project is intended to provide core functionality for a .NET Core Web API using sound (albeit opinionated) architecture and popular NuGet packages used in modern .NET Core API development.

Technologies

Project is created with:

  • .NET Core 5.0 (based on ApiBoilerPlate)
  • AutoWrapper
  • AutoMapper
  • FluentValidation
  • Scrutor
  • Serilog
  • Swashbuckle

Architecture

This starter template follows the onion architecture, although it is opionated in structure.

The onion architecture promotes loose coupling and abstracting between domain, repository, and service layers.

From the API, the hierarchy is as follows:

API --> Service --> Repository --> Domain

We can describe the advantage of this architecture by spelling out the hierarchy from bottom up:

Domain objects represent the database objects.

The Repository layer has intimate knowledge of the objects and the data access rules necessary to translate the objects from the underlying data source.

The Service layer interacts with the Repository layer (via interfaces) to perform business logic on the data to then present upward. The Service layer may also call other services (via interfaces).

The API Controllers serve as the Infrastructure layer, and generally call the Service layer (via interfaces). The API Controllers can call the Repository layer (via interfaces) but this is only if there is little to no business logic applied. General rule of thumb is to keep controller logic as light as possible... handle request, prepare response and status code.

For more information on the onion architecture, see Understanding Onion Architecture

Setup

Build the template on your local machine, from the root project

$ dotnet new -i .

The template is installed with shortname 'vbswebapi'

Now you can create your own project with your own namespace (based on the -n name). All folders, projects, and namespaces will use the name specified as the prefix.

$ dotnet new vbswebapi --help
VandenBrink Software Starter Web (C#)
Author: Steve VandenBrink
Options:                                                                              
  -mdb|--useMongoDB  Sets up MongoDB with structured logging and boilerplate   
                     bool - Optional                                           
                     Default: false / (*) true                                 

  -jwt|--useJwt      Sets up Jwt middleware and hash/salt utilities boilerplate
                     bool - Optional                                           
                     Default: false / (*) true    

For example, if you want to create a new project with the RootNamepace as 'MyProject', run the following

$ dotnet new vbswebapi -n MyProject

Then navigate to the MyProject folder created, inspect the code, and now all files are prefixed with the given namespace.

For example, Startup.cs in the API project is in namespace MyProject.API.

Make sure that after the project is created you perform:

$ dotnet restore

MongoDB

If you want to create a project that contains infrastructure for MongoDB, both for the backing data store AND structured logging, then use the --useMongoDB flag.

Example

$ dotnet new vbswebapi -n MyProject --useMongoDB

Example of Structured Logging in logs collection:

alt text

Take a look at the different appsettings which now have boilerplate for MongoDBSettings. The name specified in the -n flag will be used as application name, but you can change it to your liking.

"MongoDBSettings": {
    "ApplicationName": "MyProject",
    "Server": "localhost",
    "Port": "27017",
    "Timeout": 120,
    "Admin": "",
    "Password": ""
  }

When you specify to use Mongo, then the controller and automapper profiles will use User from MyProject.Entities/Domain/Mongo.

A [MongoDocument("users")] attribute is placed on User so that the collection name in the database is called 'users'.

Also look at the repository (concrete class and interface) to see common CRUD operations utilizing async methods on IMongoDatabase.

Example of 'users' collection:

Jwt Authentication

If you want to create a project that has infrastructure for Jwt authentication, then use the --useJwt flag.

When combined with the --useMongoDB flag, you have access to a full repository implementation that will register a user to the backing Mongo database and when logging in as that user you will receive a token with a few claims.

Please note that when jwt is used the [Authorize] attribute is placed on the UsersController and testing in Swagger will no longer work at this time.

A postman collection is contained in the repo so that you can import and use to test endpoints with authentication (using Bearer).

Unit Tests

An additional parameter can be specified to include unit tests with xUnit, Moq, and the coverlet.msbuild package to generate coverage reports (can feed into SonarQube).

Presently this flag only works if you are using MongoDB and Jwt.

dotnet new vbswebapi -n MyProject --useMongoDB --useJwt --useTests

Also, since this template includes a preconfigured solution, the tests project will have to be added to the solution. Dotnet templates do not currently support conditionals for .sln files based on their documentation.

dotnet sln MyProject.API.sln add MyProject.API.Tests

Jenkins and SonarQube

Additional parameters can be specified to set up Jenkins CI with Code Coverage and Test Results

dotnet new vbswebapi -n MyProject --useJenkinsfile --sonarServer https://<server> --sonarProjectKey <sonar_project_key> --sonarProjectLogin <sonar_project_login>

Test API

Run the project

$ dotnet run

Open a web browser at localhost:5000/swagger

alt text

Get Users

Try out and execute GET /api/Users

If you are not using MongoDB: You will get a 200 response with 1 user returned

If you are using MongoDB: You will get a 200 response with the users returned from the 'users' collection (may not yet exist)

POST New User

Try out and execute POST /api/Users

Update the request JSON body to your liking.

If you are not using MongoDB: You will get a 200 response with 1 user returned including a dummy ID that the server might generate from the backing database.

If you are using MongoDB: You will get a 200 response with the user returned and an ObjectId (_id) set.

Additionally, try empty strings or deleting properties in the JSON body entirely. You will get a 400 type response with a list of validation errors (this is FluentValidation at work!).

GET Specifc User

Try out and execute GET /api/Users/{id}

If you are not using MongoDB: You will get a 200 response with the desired user returned with that id.

If you are using MongoDB: You will get a 200 response with the desire user returned from the 'users' collection.

netcore-webapi-starter's People

Contributors

vb-software avatar

netcore-webapi-starter's Issues

Refactoring infrastructure for Mongo

The following refactorings need to occur:

  • DTOs

    • UserForLogin
      • Add fluent validation to ensure username and password not empty
    • UserForRegister
      • Add fluent validation to ensure firstName, lastName, username, and password not empty
      • Add fluent validation on name/password to ensure min length of characters
    • Change class names to have Dto (camel case)
  • AutoMapper

    • Add profiles
      • UserForLoginDto -> User
      • UserForRegisterDto -> User
  • UsersController

    • Change get user by id to pass in a userId of type Guid (change repository appropriately also)

Add boilerplate unit tests with option flag

Need to add tests that are optional when creating the project.

Tests will cover the 2 controllers (auth, users)
Test coverage needs to be at 100%

Use xUnit, add coverage reporter, and include template for sonar properties xml

Consider adding item template for creating Mongo Repository implementations and creating a template pack that includes both the current project and new item templates

For every Mongo collection in the application:

  • Entity is created in Domain/Mongo to represent object in collection
  • Repository interface with standard CRUD interfaces
  • Repository implementation against interface
    • Constructor takes in MongoDbSettings from DI
    • GetGlobalCollection is called where T is the new entity

In addition to providing an item template to facilitate scaffolding mongo collections, this template should be packed with the current project template so that both are installed when the template pack is installed.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.