Coder Social home page Coder Social logo

recessopinionatedapiinaspnetcore's Introduction

Recess - An Opinionated API Architecture for ASP.NET Core

Overview

This project is meant to serve as a working example for the talk, An Opinionated, Maintainable REST Architecture for ASP.NET Core. It's highly recommended that you either a) watch the talk or b) start reading a ton of Jimmy Bogard's blog posts. Go ahead, I'll wait.

What is it?

This project is an opinion by Spencer Schneidenbach about how APIs can be architected (from a code perspective) using ASP.NET Core.

Let me be clear - when I say architecture, I mean how the code is structured. Definitely not a full system architecture!

It's meant to be turnkey, but only as an experiment. If you really want, you can clone it and use it as a template, but make sure you know what you're getting you and your team into.

Manifesto

  • Separation of concerns is a good thing.
  • Every action is broken down into requests (aka commands) and handlers. Requests gives the handlers enough information to do their jobs. Simply put...
  • ...CQRS is a good thing.
  • Entities should never be used to represent data in APIs - everything should go through a dumb object, or DTO, that is nothing but data.
  • Controllers should know where to go to process a request, not how to process the request. Always and forever.
  • Functionality should be separated by domain, not by category. Notice no Controllers or Models folders - Jobs and Employees (our example objects) are in their own folders.

You will agree with some of my decisions. You will also disagree with some of my decisions. The main point of this is to provide my opinions so you can form your own!

Libraries used

  • MediatR - this in-memory process delegator is the core of the project - it knows where to take requests for processing.
  • Autofac - my favorite dependency injection library. Wires all of the project's dependencies together in a convenient, easy-to-understand way.
  • AutoMapper - everyone's favorite mapper library for .NET. Easily define mappings between classes. ProjectTo is our god.
  • FluentValidation - a deceptively simple way of validating requests coming into MediatR. Better than attribute validation.
  • Entity Framework Core - my favorite way to access data (except for EF6). You don't have to use it - anything that gives you an IQueryable is good enough. This is pretty nice cause you get an in-memory database for free.
  • AutoMapper.Attributes - a personal project of mine. Allows you to define mappings between classes using attributes.

Features

  • Paging when doing GETs
  • OrderBy for requests

Getting started

  1. Make sure you have the .NET Core SDK installed.
  2. Clone the repo.
  3. CD into src, then OpinionatedApiExample.
  4. Run dotnet restore.
  5. Run dotnet run.

Experimentation

When you run the app, it won't look like it does anything. I'd start by firing up Postman or curl or whatever you like, and start making requests to:

GET /api/Employees
POST /api/Employees
GET /api/Employees/1
GET /api/Jobs
POST /api/Jobs

and see what happens.

Brief tour

This part is a stub. It needs to be greatly expanded.

The main thing you should be aware of is the fact that everything is broken down into requests and handlers. Requests represent a thing you want to do. Handlers take requests and performs the corresponding action - either get some data, create an object, etc. Validators can be used to make sure that requests are valid before they're processed.

Everything is decoupled. Requests are separate classes from handlers are separate classes from validators. The OpinionatedRestController is kind of my version of scaffolding - a lot of the magic is taken care of for you for GETs, PUTs, and POSTs. Just override and enjoy. Because you can always refactor later, right?? Right. :)

WARNING: the PUT method as implemented is pretty weak! Like, super weak. It could be used to write to properties you didn't intend for your users to write to - it's more demonstrative than anything. YOU HAVE BEEN WARNED!

There are two implemented APIs that you can peruse - Jobs and Employees. Both are roughly the same, but Job has a dependency on Employee.

Employees

Employees are pretty basic objects, but represent something with a common business rule - properties that you want to be able to write to but not necessarily read from. This is represented by our use of the SocialSecurityNumber property.

  • Employee.cs - the entity that is used by Entity Framework to store and retrieve Employee records. Has the SocialSecurityNumber property.
  • EmployeeModel.cs - the DTO we use in GET requests. Note its lack of the SocialSecurityNumber property - we don't want to be able to read this.
  • CreateEmployeeModel.cs - the DTO we use in POST (create) requests. Note that it DOES have the SocialSecurityNumber property for when the object is created.
  • CreateEmployeeValidator.cs - the class that validates the EmployeePostModel. Makes sure incoming Employees have at least a first and last name.
  • EmployeesController.cs - routes the requests to handlers. Most of the magic happens through the OpinionatedRestController.

Jobs

Jobs are pretty basic objects, but require an Employee object to be associated to them. Pretty common use case.

  • Job.cs - the entity that is used by Entity Framework to store and retrieve Job records.
  • JobModel.cs - the DTO we use in GET requests.
  • CreateJobModel.cs - the DTO we use in POST (create) requests. Note that it has an ProjectManagerId as a required parameter - this is where you pass in the ID of the Employee.
  • CreateJobValidator.cs - the class that validates the JobPostModel. Note that it checks to make sure the Employee ID you're passing in via ProjectManagerId points to an existing Employee.
  • EmployeesController.cs - routes the requests to handlers.

TODOs

  • More comprehensive tests
  • Expanded documentation
  • Comments in code so it's explictly clear how/why stuff is done

License

MIT.

Thank you

Jimmy Bogard's blog and talks served as the biggest inspiration for this talk and this project. His libraries AutoMapper and MediatR stand at the core of this project. Basically I'm standing on the shoulders of giants.

recessopinionatedapiinaspnetcore's People

Contributors

schneidenbach avatar

Watchers

James Cloos avatar Sébastien Putier avatar

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.