Convert Figma logo to code with AI

gothinkster logospring-boot-realworld-example-app

Example Spring codebase containing real world examples (CRUD, auth, advanced patterns, etc) that adheres to the RealWorld API spec.

1,296
673
1,296
1

Top Related Projects

ASP.NET Core backend implementation for RealWorld

Exemplary real world backend API built with Laravel

Quick Overview

The gothinkster/spring-boot-realworld-example-app is a Spring Boot implementation of the RealWorld backend API spec. It serves as a demonstration of how to build a real-world application using Spring Boot, following best practices and modern development techniques. This project is part of the larger RealWorld initiative, which aims to create exemplary fullstack applications across various tech stacks.

Pros

  • Implements a comprehensive, real-world API specification
  • Uses Spring Boot, a popular and well-supported framework for Java applications
  • Follows best practices and modern development techniques
  • Serves as an excellent learning resource for developers

Cons

  • May be complex for beginners to understand all aspects of the implementation
  • Requires knowledge of Java and Spring Boot ecosystem
  • Limited documentation on project-specific implementation details
  • May require updates to keep up with evolving Spring Boot versions and best practices

Code Examples

Here are a few code examples from the project:

  1. User registration endpoint:
@PostMapping("/users")
public ResponseEntity createUser(@Valid @RequestBody RegisterParam registerParam) {
    User user = userService.createUser(registerParam);
    UserWithToken userWithToken = userService.userWithToken(user);
    return ResponseEntity.status(201).body(userWithToken);
}

This code defines a POST endpoint for user registration, validating the input and returning the created user with a token.

  1. Article creation:
@PostMapping("/articles")
public ResponseEntity createArticle(@Valid @RequestBody NewArticleParam newArticleParam,
                                    @AuthenticationPrincipal User currentUser) {
    Article article = articleService.createArticle(newArticleParam, currentUser);
    return ResponseEntity.status(201).body(articleResponse(article));
}

This code handles the creation of a new article, using the authenticated user as the author.

  1. JWT authentication filter:
@Component
public class JwtTokenFilter extends OncePerRequestFilter {
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        String token = jwtTokenProvider.resolveToken(request);
        if (token != null && jwtTokenProvider.validateToken(token)) {
            Authentication auth = jwtTokenProvider.getAuthentication(token);
            SecurityContextHolder.getContext().setAuthentication(auth);
        }
        filterChain.doFilter(request, response);
    }
}

This code implements a JWT token filter for authentication, validating the token and setting the authentication context.

Getting Started

To get started with this project:

  1. Clone the repository:

    git clone https://github.com/gothinkster/spring-boot-realworld-example-app.git
    
  2. Navigate to the project directory:

    cd spring-boot-realworld-example-app
    
  3. Build and run the application:

    ./gradlew bootRun
    
  4. The API will be available at http://localhost:8080/api

For more detailed instructions and API documentation, refer to the project's README file.

Competitor Comparisons

Pros of node-express-realworld-example-app

  • Lightweight and faster development due to JavaScript's simplicity
  • Larger ecosystem of npm packages for quick feature implementation
  • Non-blocking I/O model for better performance in high-concurrency scenarios

Cons of node-express-realworld-example-app

  • Less robust type checking compared to Java's static typing
  • Potential for callback hell in asynchronous operations
  • Lack of built-in multithreading support for CPU-intensive tasks

Code Comparison

node-express-realworld-example-app:

router.post('/users', async (req, res, next) => {
  try {
    const user = await User.create(req.body.user);
    return res.json({user: user.toAuthJSON()});
  } catch(error) {
    return next(error);
  }
});

spring-boot-realworld-example-app:

@PostMapping("/users")
public ResponseEntity<UserResponse> createUser(@Valid @RequestBody NewUserRequest newUserRequest) {
    User user = userService.createUser(newUserRequest);
    return ResponseEntity.status(HttpStatus.CREATED)
            .body(UserResponse.fromUserAndToken(user, jwtService.toToken(user)));
}

The Node.js example uses async/await for handling asynchronous operations, while the Spring Boot example utilizes Java's synchronous approach with built-in validation annotations. The Spring Boot version provides more explicit type definitions and HTTP status handling.

ASP.NET Core backend implementation for RealWorld

Pros of aspnetcore-realworld-example-app

  • Built on ASP.NET Core, offering excellent performance and cross-platform compatibility
  • Utilizes Entity Framework Core for efficient database operations
  • Implements a clean architecture with separation of concerns

Cons of aspnetcore-realworld-example-app

  • Less extensive community support compared to Spring Boot ecosystem
  • Fewer third-party libraries and integrations available
  • Steeper learning curve for developers not familiar with .NET ecosystem

Code Comparison

spring-boot-realworld-example-app:

@GetMapping("/articles/{slug}")
public ResponseEntity<SingleArticleResponse> getArticle(@PathVariable("slug") String slug) {
    return articleQueryService.findBySlug(slug)
            .map(article -> ResponseEntity.ok(SingleArticleResponse.fromArticle(article)))
            .orElseThrow(ResourceNotFoundException::new);
}

aspnetcore-realworld-example-app:

[HttpGet("{slug}")]
public async Task<IActionResult> Get(string slug)
{
    var article = await _articleRepository.GetArticleBySlug(slug);
    if (article == null)
        return NotFound();
    return Ok(new { article = _mapper.Map<ArticleResponse>(article) });
}

Both implementations handle article retrieval by slug, but the ASP.NET Core version uses async/await for better scalability. The Spring Boot version uses Java 8 Optional for null handling, while the ASP.NET Core version checks for null explicitly.

Exemplary real world backend API built with Laravel

Pros of laravel-realworld-example-app

  • Simpler setup and configuration due to Laravel's convention-over-configuration approach
  • Built-in support for authentication and authorization using Laravel's native features
  • More extensive documentation and larger community support for Laravel

Cons of laravel-realworld-example-app

  • Less scalable for large, enterprise-level applications compared to Spring Boot
  • Potentially slower performance, especially under high load, due to PHP's interpreted nature
  • Limited options for microservices architecture compared to Spring Boot's ecosystem

Code Comparison

Laravel (PHP):

public function login(Request $request)
{
    $credentials = $request->only('email', 'password');
    if (Auth::attempt($credentials)) {
        return $this->respondWithToken(Auth::user()->generateToken());
    }
    return response()->json(['error' => 'Unauthorized'], 401);
}

Spring Boot (Java):

@PostMapping("/login")
public ResponseEntity<?> login(@RequestBody LoginRequest loginRequest) {
    Authentication authentication = authenticationManager.authenticate(
        new UsernamePasswordAuthenticationToken(loginRequest.getEmail(), loginRequest.getPassword())
    );
    SecurityContextHolder.getContext().setAuthentication(authentication);
    String jwt = jwtTokenProvider.generateToken(authentication);
    return ResponseEntity.ok(new JwtAuthenticationResponse(jwt));
}

The Laravel example showcases its simplicity in handling authentication, while the Spring Boot example demonstrates its more verbose but flexible approach to security and token generation.

Pros of django-realworld-example-app

  • Simpler and more lightweight framework, easier to set up and get started
  • Better suited for smaller to medium-sized projects
  • More flexibility in architectural choices and design patterns

Cons of django-realworld-example-app

  • Less robust for large-scale enterprise applications compared to Spring Boot
  • Fewer built-in features and integrations out of the box
  • Potentially slower performance for high-traffic applications

Code Comparison

Django (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

Spring Boot (spring-boot-realworld-example-app):

@RestController
@RequestMapping(path = "/articles")
class ArticleController {
    private final ArticleRepository articleRepository;
    private final UserRepository userRepository;

    @GetMapping
    public ResponseEntity<?> getArticles(@RequestParam(value = "offset", defaultValue = "0") int offset,
                                         @RequestParam(value = "limit", defaultValue = "20") int limit) {
        return ResponseEntity.ok(articleRepository.findAll(new PageRequest(offset, limit)));
    }
}

Both examples showcase the implementation of article-related functionality, with Django using a ViewSet approach and Spring Boot using a RestController. The Django code appears more concise, while the Spring Boot code offers more explicit request mapping and dependency injection.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

RealWorld Example App using Kotlin and Spring

Actions

Spring boot + MyBatis codebase containing real world examples (CRUD, auth, advanced patterns, etc) that adheres to the RealWorld spec and API.

This codebase was created to demonstrate a fully fledged full-stack application built with Spring boot + Mybatis including CRUD operations, authentication, routing, pagination, and more.

For more information on how to this works with other frontends/backends, head over to the RealWorld repo.

NEW GraphQL Support

Following some DDD principles. REST or GraphQL is just a kind of adapter. And the domain layer will be consistent all the time. So this repository implement GraphQL and REST at the same time.

The GraphQL schema is https://github.com/gothinkster/spring-boot-realworld-example-app/blob/master/src/main/resources/schema/schema.graphqls and the visualization looks like below.

And this implementation is using dgs-framework which is a quite new java graphql server framework.

How it works

The application uses Spring Boot (Web, Mybatis).

  • Use the idea of Domain Driven Design to separate the business term and infrastructure term.
  • Use MyBatis to implement the Data Mapper pattern for persistence.
  • Use CQRS pattern to separate the read model and write model.

And the code is organized as this:

  1. api is the web layer implemented by Spring MVC
  2. core is the business model including entities and services
  3. application is the high-level services for querying the data transfer objects
  4. infrastructure contains all the implementation classes as the technique details

Security

Integration with Spring Security and add other filter for jwt token process.

The secret key is stored in application.properties.

Database

It uses a H2 in-memory database sqlite database (for easy local test without losing test data after every restart), can be changed easily in the application.properties for any other database.

Getting started

You'll need Java 11 installed.

./gradlew bootRun

To test that it works, open a browser tab at http://localhost:8080/tags .
Alternatively, you can run

curl http://localhost:8080/tags

Try it out with Docker

You'll need Docker installed.

./gradlew bootBuildImage --imageName spring-boot-realworld-example-app
docker run -p 8081:8080 spring-boot-realworld-example-app

Try it out with a RealWorld frontend

The entry point address of the backend API is at http://localhost:8080, not http://localhost:8080/api as some of the frontend documentation suggests.

Run test

The repository contains a lot of test cases to cover both api test and repository test.

./gradlew test

Code format

Use spotless for code format.

./gradlew spotlessJavaApply

Help

Please fork and PR to improve the project.