All Projects → helpermethod → Spring Boot Style Guide

helpermethod / Spring Boot Style Guide

Licence: mit
An opinionated guide on developing web applications with Spring Boot.

Projects that are alternatives of or similar to Spring Boot Style Guide

Hex Arch Kotlin Spring Boot
Reference JVM multi module project for a reactive micro service and lambda using a hexagonal architecture, DDD, Kotlin, Spring Boot, Quarkus, Lambda, Gradle.
Stars: ✭ 83 (-5.68%)
Mutual labels:  spring-boot, spring
Spring Ws
Spring WS Tutorials
Stars: ✭ 75 (-14.77%)
Mutual labels:  spring-boot, spring
Curso Sistemas Web Com Spring Javascript Bootstrap
Stars: ✭ 74 (-15.91%)
Mutual labels:  spring-boot, spring
Spring Boot Jwt Demo
Simplest jwt demo with only 3 classes. Simple but product-level .
Stars: ✭ 86 (-2.27%)
Mutual labels:  spring-boot, spring
Telegram Spring Boot Starter
Telegram Bot API Spring Boot Starter
Stars: ✭ 79 (-10.23%)
Mutual labels:  spring-boot, spring
Spring Boot Webflux Jjwt
Example Spring Boot and WebFlux (Reactive Web) with Spring Security and JWT for token Authentication and Authorization
Stars: ✭ 71 (-19.32%)
Mutual labels:  spring-boot, spring
Guide
The Uber Go Style Guide.
Stars: ✭ 10,140 (+11422.73%)
Mutual labels:  best-practices, style-guide
Eshop Soa
EShop基于Dubbo实现SOA服务化拆分,并基于RocketMQ解决了分布式事务(新版SpringBootSOASkeleton)
Stars: ✭ 65 (-26.14%)
Mutual labels:  spring-boot, spring
Spring Boot Mongodb Angular Todo App
A Sample App built using Spring Boot, Angular and MongoDB
Stars: ✭ 84 (-4.55%)
Mutual labels:  spring-boot, spring
Deploy Spring Boot Aws Eb
Deploying Spring Boot Apps to AWS using Elastic Beanstalk
Stars: ✭ 79 (-10.23%)
Mutual labels:  spring-boot, spring
Spring Cloud Cloudfoundry
Integration between Cloudfoundry and the Spring Cloud APIs
Stars: ✭ 83 (-5.68%)
Mutual labels:  spring-boot, spring
Spring Boot Shopping Cart
Simple shopping cart web app made using Spring Boot + Thymeleaf
Stars: ✭ 85 (-3.41%)
Mutual labels:  spring-boot, spring
Web Development Interview With Java
Java 开发相关技术栈(大中厂)高频面试问题收录。
Stars: ✭ 69 (-21.59%)
Mutual labels:  spring-boot, spring
Electron Vue Spring
An opinionated desktop application with web front-end and Java backend.
Stars: ✭ 83 (-5.68%)
Mutual labels:  spring-boot, spring
Intellij Spring Assistant
Spring Assistant - IntelliJ plugin that assists you in developing spring applications
Stars: ✭ 64 (-27.27%)
Mutual labels:  spring-boot, spring
Okta Blog Archive
Okta Developer Blog
Stars: ✭ 74 (-15.91%)
Mutual labels:  spring-boot, spring
Quartz Demo
Demo project for Spring Boot 2 and Quartz scheduler integration
Stars: ✭ 63 (-28.41%)
Mutual labels:  spring-boot, spring
Spring Higher Order Components
⚡️ Preconfigured components to speedup Spring Boot development
Stars: ✭ 65 (-26.14%)
Mutual labels:  spring-boot, spring
Rqueue
Rqueue aka Redis Queue [Task Queue, Message Broker] for Spring framework
Stars: ✭ 76 (-13.64%)
Mutual labels:  spring-boot, spring
Redisratelimiter
Redis Based API Access Rate Limiter
Stars: ✭ 80 (-9.09%)
Mutual labels:  spring-boot, spring

Spring Boot Style Guide

An opinionated guide on developing web applications with Spring Boot. Inspired by Airbnb JavaScript Style Guide.

Join the chat at https://gitter.im/helpermethod/spring-boot-style-guide License

Table of Contents

Dependency Injection

  • Use constructor injection. Avoid field injection.

Why? Constructor injection makes dependencies explicit and forces you to provide all mandatory dependencies when creating instances of your component.

// bad
public class PersonService {
    @AutoWired
    private PersonRepository personRepositoy;
}

// good
public class PersonService {
    private final PersonRepository personRepository;

    // if the class has only one constructor, @Autowired can be omitted
    public PersonService(PersonRepository personRepository) {
        this.personRepository = personRepository;
    }
}    
  • Avoid single implementation interfaces.

Why? A class already exposes an interface: its public members. Adding an identical interface definition makes the code harder to navigate and violates YAGNI.

What about testing? Earlier mocking frameworks were only capable of mocking interfaces. Recent frameworks like Mockito can also mock classes.

// bad
public interface PersonService {
    List<Person> getPersons();
}

public class PersonServiceImpl implements PersonService {
    public List<Person> getPersons() {
        // more code
    }
}

// good
public class PersonService {
    public List<Person> getPersons() {
        // more code
    }
}

⬆ back to top

Controllers

  • Use @RestController when providing a RESTful API.
// bad
@Controller
public class PersonController {
    @ResponseBody
    @GetMapping("/persons/{id}")
    public Person show(@PathVariable long id) {
        // more code
    }
}

// good
@RestController
public class PersonController {
    @GetMapping("/persons/{id}")
    public Person show(@PathVariable long id) {
        // more code
    }
}
  • Use @GetMapping, @PostMapping etc. instead of @RequestMapping.
// bad
@RestController
public class PersonController {
    @RequestMapping(method = RequestMethod.GET, value = "/persons/{id}")
    public Person show(@PathVariable long id) {
        // more code
    }
}

// good
@RestController
public class PersonController {
    @GetMapping("/persons/{id}")
    public Person show(@PathVariable long id) {
        // more code
    }
}

⬆ back to top

Serialization

  • Do not map your JSON objects to JavaBeans.

Why? JavaBeans are mutable and split object construction across multiple calls.

// bad
public class Person {
    private String firstname;
    private String lastname;

    public void setFirstname() {
        this.firstname = firstname;
    }

    public String getFirstname() {
        return firstname;
    }

    public void setLastname() {
        this.lastname = lastname;
    }

    public String getLastname() {
        return lastname;
    }
}

// good
public class Person {
    private final String firstname;
    private final String lastname;

    // requires your code to be compiled with a Java 8 compliant compiler 
    // with the -parameter flag turned on
    // as of Spring Boot 2.0 or higher, this is the default
    @JsonCreator
    public Person(String firstname, String lastname) {
        this.firstname = firstname;
        this.lastname = lastname;
    }

    public String getFirstname() {
        return firstname;
    }

    public String getLastname() {
        return lastname;
    }
}

// best
public class Person {
    private final String firstname;
    private final String lastname;

    // if the class has a only one constructor, @JsonCreator can be omitted
    public Person(String firstname, String lastname) {
        this.firstname = firstname;
        this.lastname = lastname;
    }

    public String getFirstname() {
        return firstname;
    }

    public String getLastname() {
        return lastname;
    }
}

⬆ back to top

Testing

  • Keep Spring out of your unit tests.
class PersonServiceTests {
    @Test
    void testGetPersons() {
        // given
        PersonRepository personRepository = mock(PersonRepository.class);
        when(personRepository.findAll()).thenReturn(List.of(new Person("Oliver", "Weiler")));

        PersonService personService = new PersonService(personRepository);

        // when
        List<Person> persons = personService.getPersons();

        // then
        assertThat(persons).extracting(Person::getFirstname, Person::getLastname).containsExactly("Oliver", "Weiler");
    }
}

Why? AssertJ is more actively developed, requires only one static import, and allows you to discover assertions through autocompletion.

// bad
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.empty;

assertThat(persons), is(not(empty())));

// good
import static org.assertj.core.api.Assertions.assertThat;

assertThat(persons).isNotEmpty();

⬆ back to top

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].