Top Related Projects
Example Spring codebase containing real world examples (CRUD, auth, advanced patterns, etc) that adheres to the RealWorld API spec.
Exemplary real world backend API built with Laravel
Exemplary real world application built with Golang + Gin
Quick Overview
The gothinkster/aspnetcore-realworld-example-app is a full-stack implementation of the "RealWorld" application using ASP.NET Core and Angular. It serves as a demonstration of how to build a real-world application with these technologies, following best practices and modern development patterns.
Pros
- Provides a complete, production-ready example of a full-stack application
- Implements a standardized API specification, making it easy to compare with other implementations
- Uses modern ASP.NET Core features and practices
- Includes comprehensive unit and integration tests
Cons
- May be overwhelming for beginners due to its complexity
- Requires knowledge of both backend (C#, ASP.NET Core) and frontend (Angular) technologies
- Some dependencies may become outdated over time if not regularly maintained
- Limited documentation for customization and extension
Code Examples
Here are a few code examples from the project:
- User registration endpoint:
[HttpPost]
public async Task<IActionResult> Create([FromBody] RegisterUser.Command command)
{
await Mediator.Send(command);
return Ok();
}
This code defines an HTTP POST endpoint for user registration, using MediatR to handle the command.
- Article creation:
public async Task<ArticleEnvelope> Handle(Create.Command request)
{
var author = await _context.Persons.FirstAsync(x => x.Username == _currentUserAccessor.GetCurrentUsername());
var article = new Article()
{
Author = author,
Body = request.Article.Body,
CreatedAt = DateTime.UtcNow,
UpdatedAt = DateTime.UtcNow,
Description = request.Article.Description,
Title = request.Article.Title,
Slug = request.Article.Title.GenerateSlug()
};
await _context.Articles.AddAsync(article);
await _context.SaveChangesAsync();
return new ArticleEnvelope(article);
}
This code handles the creation of a new article, associating it with the current user and generating a slug.
- JWT token generation:
public string GenerateToken(Person user)
{
var claims = new[]
{
new Claim(JwtRegisteredClaimNames.Sub, user.Username),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
new Claim(JwtRegisteredClaimNames.UniqueName, user.Username)
};
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_jwtOptions.SecretKey));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var token = new JwtSecurityToken(
issuer: _jwtOptions.Issuer,
audience: _jwtOptions.Audience,
claims: claims,
expires: DateTime.UtcNow.AddMinutes(_jwtOptions.ExpirationMinutes),
signingCredentials: creds);
return new JwtSecurityTokenHandler().WriteToken(token);
}
This code generates a JWT token for user authentication, including claims and an expiration time.
Getting Started
To get started with this project:
-
Clone the repository:
git clone https://github.com/gothinkster/aspnetcore-realworld-example-app.git
-
Navigate to the project directory and restore dependencies:
cd aspnetcore-realworld-example-app dotnet restore
-
Run the application:
dotnet run
-
Access the API at
http://localhost:5000
and the Angular frontend athttp://localhost:4200
.
Competitor Comparisons
Pros of node-express-realworld-example-app
- Lightweight and faster development due to JavaScript's simplicity
- Larger ecosystem with more npm packages available
- Better suited for small to medium-sized applications
Cons of node-express-realworld-example-app
- Less robust type checking compared to C#'s static typing
- Potential performance limitations for CPU-intensive tasks
- Lack of built-in modularity compared to ASP.NET Core's architecture
Code Comparison
node-express-realworld-example-app:
router.post('/users', async (req, res, next) => {
const user = new User();
user.username = req.body.user.username;
user.email = req.body.user.email;
user.setPassword(req.body.user.password);
await user.save();
return res.json({ user: user.toAuthJSON() });
});
aspnetcore-realworld-example-app:
[HttpPost]
public async Task<IActionResult> Create([FromBody] RegisterUser command)
{
await _mediator.Send(command);
var user = await _context.Users.FirstAsync(x => x.Email == command.Email);
return CreatedAtAction(nameof(Get), new { username = user.Username }, user.ToUserResponse());
}
The Node.js example uses a more straightforward approach with direct database operations, while the ASP.NET Core example employs the mediator pattern and separates concerns more explicitly. The ASP.NET Core version also benefits from stronger typing and built-in dependency injection.
Example Spring codebase containing real world examples (CRUD, auth, advanced patterns, etc) that adheres to the RealWorld API spec.
Pros of spring-boot-realworld-example-app
- Utilizes Spring Boot, which offers rapid development and easy configuration
- Implements a more modular architecture with clear separation of concerns
- Provides comprehensive test coverage, including integration tests
Cons of spring-boot-realworld-example-app
- May have a steeper learning curve for developers new to Spring ecosystem
- Potentially higher memory footprint due to Spring Boot's auto-configuration
Code Comparison
spring-boot-realworld-example-app:
@RestController
@RequestMapping(path = "/api/users")
class UsersApi {
@Autowired
private UserRepository userRepository;
@PostMapping
public ResponseEntity createUser(@Valid @RequestBody RegisterParam registerParam) {
// User creation logic
}
}
aspnetcore-realworld-example-app:
[Route("api/[controller]")]
public class UsersController : Controller
{
private readonly IUserService _userService;
public UsersController(IUserService userService)
{
_userService = userService;
}
[HttpPost]
public async Task<IActionResult> Create([FromBody] CreateUserRequest request)
{
// User creation logic
}
}
Both examples showcase similar API structures, but spring-boot-realworld-example-app uses annotations for dependency injection and request mapping, while aspnetcore-realworld-example-app uses constructor injection and attribute routing. The Spring Boot example demonstrates a more concise approach to defining REST endpoints.
Exemplary real world backend API built with Laravel
Pros of laravel-realworld-example-app
- Utilizes Laravel's elegant syntax and robust ecosystem, making it easier for PHP developers to understand and extend
- Includes built-in authentication and authorization features, simplifying user management
- Offers a more comprehensive set of features out-of-the-box, such as database migrations and seeders
Cons of laravel-realworld-example-app
- May have slower performance compared to ASP.NET Core, especially for high-traffic applications
- Less suitable for developers with a strong C# background or those working in a Microsoft-centric environment
- Limited cross-platform compatibility compared to ASP.NET Core
Code Comparison
Laravel (PHP):
public function index()
{
$articles = Article::with('tags')->latest()->paginate(20);
return ArticleResource::collection($articles);
}
ASP.NET Core (C#):
public async Task<IActionResult> Index()
{
var articles = await _context.Articles.Include(a => a.Tags)
.OrderByDescending(a => a.CreatedAt)
.Take(20).ToListAsync();
return Ok(articles);
}
Both examples show a method for retrieving articles, but Laravel's approach is more concise due to its built-in ORM and resource classes. ASP.NET Core requires more explicit coding but offers more control over the query and response.
Pros of django-realworld-example-app
- Simpler setup and configuration due to Django's "batteries included" philosophy
- More straightforward ORM with Django models, making database operations easier
- Faster development cycle for small to medium-sized projects
Cons of django-realworld-example-app
- Less scalable for large, complex applications compared to ASP.NET Core
- Limited built-in support for real-time features like WebSockets
- Potentially slower performance for high-traffic applications
Code Comparison
django-realworld-example-app:
class ArticleViewSet(mixins.CreateModelMixin,
mixins.ListModelMixin,
mixins.RetrieveModelMixin,
viewsets.GenericViewSet):
lookup_field = 'slug'
queryset = Article.objects.select_related('author', 'author__user')
permission_classes = (IsAuthenticatedOrReadOnly,)
serializer_class = ArticleSerializer
aspnetcore-realworld-example-app:
[Route("api/[controller]")]
public class ArticlesController : Controller
{
private readonly IArticleRepository _articleRepository;
private readonly IMapper _mapper;
public ArticlesController(IArticleRepository articleRepository, IMapper mapper)
{
_articleRepository = articleRepository;
_mapper = mapper;
}
}
The Django example uses a class-based view with mixins, while the ASP.NET Core example uses a controller with dependency injection. Django's approach is more concise, but ASP.NET Core's approach offers more flexibility and separation of concerns.
Exemplary real world application built with Golang + Gin
Pros of golang-gin-realworld-example-app
- Faster execution and lower memory footprint due to Go's efficiency
- Simpler concurrency model with goroutines and channels
- Easier deployment with a single binary executable
Cons of golang-gin-realworld-example-app
- Less mature ecosystem compared to .NET Core
- Fewer built-in features and libraries for web development
- Steeper learning curve for developers coming from C# background
Code Comparison
aspnetcore-realworld-example-app (C#):
public async Task<IActionResult> GetArticle(string slug)
{
var article = await _context.Articles
.Include(x => x.Author)
.FirstOrDefaultAsync(x => x.Slug == slug);
if (article == null)
return NotFound();
return Ok(new { article = await _articles.GetArticle(article) });
}
golang-gin-realworld-example-app (Go):
func GetArticle(c *gin.Context) {
slug := c.Param("slug")
article, err := articleModel.GetBySlug(slug)
if err != nil {
c.JSON(http.StatusNotFound, utils.NewError("articles", errors.New("Invalid slug")))
return
}
serializer := ArticleSerializer{c, article}
c.JSON(http.StatusOK, gin.H{"article": serializer.Response()})
}
Both examples demonstrate similar functionality for retrieving an article by slug, but the Go version is more concise and uses Gin's context for handling HTTP requests and responses.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
ASP.NET Core codebase containing real world examples (CRUD, auth, advanced patterns, etc) that adheres to the RealWorld spec and API.
RealWorld
This codebase was created to demonstrate a fully fledged fullstack application built with ASP.NET Core (with Feature orientation) including CRUD operations, authentication, routing, pagination, and more.
We've gone to great lengths to adhere to the ASP.NET Core community styleguides & best practices.
For more information on how to this works with other frontends/backends, head over to the RealWorld repo.
How it works
This is using ASP.NET Core with:
- CQRS and MediatR
- AutoMapper
- Fluent Validation
- Feature folders and vertical slices
- Entity Framework Core on SQLite for demo purposes. Can easily be anything else EF Core supports. Open to porting to other ORMs/DBs.
- Built-in Swagger via Swashbuckle.AspNetCore
- Bullseye for building!
- JWT authentication using ASP.NET Core JWT Bearer Authentication.
- Use dotnet-format for style checking
.editorconfig
to enforce some usage patterns
This basic architecture is based on this reference architecture: https://github.com/jbogard/ContosoUniversityCore
Getting started
Install the .NET Core SDK and lots of documentation: https://www.microsoft.com/net/download/core
Documentation for ASP.NET Core: https://docs.microsoft.com/en-us/aspnet/core/
Docker Build
There is a 'Makefile' for OS X and Linux:
make build
executesdocker-compose build
make run
executesdocker-compose up
The above might work for Docker on Windows
Local building
- It's just another C# file!
dotnet run -p build/build.csproj
Swagger URL
http://localhost:5000/swagger
GitHub Actions build
Top Related Projects
Example Spring codebase containing real world examples (CRUD, auth, advanced patterns, etc) that adheres to the RealWorld API spec.
Exemplary real world backend API built with Laravel
Exemplary real world application built with Golang + Gin
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot