사용한 코드

List<TodoDTO> dtos = entities.stream().map(TodoDTO::new).collect(Collectors.toList());

https://dpdpwl.tistory.com/81

 

[Java]자바 스트림Stream(map,filter,sorted / collect,foreach)

자바8부터 Stream 을 사용 할 수 있습니다. 기존에 자바 컬렉션이나 배열의 원소를 가공할떄, for문, foreach 등으로 원소 하나씩 골라내여 가공을 하였다면, Stream 을 이용하여 람다함수형식으로 간결

dpdpwl.tistory.com

https://www.geeksforgeeks.org/double-colon-operator-in-java/

 

Double colon (::) operator in Java - GeeksforGeeks

A Computer Science portal for geeks. It contains well written, well thought and well explained computer science and programming articles, quizzes and practice/competitive programming/company interview Questions.

www.geeksforgeeks.org

 

final Optional<TodoEntity> original = repository.findById(entity.getId());

log.warn(original.toString());

if(original.isPresent()) {
    // (3) 반환된 TodoEntity가 존재하면 값을 새 entity 값으로 덮어 씌운다.
    final TodoEntity todo = original.get();
    todo.setTitle(entity.getTitle());
    todo.setDone(entity.isDone());

    // (4) 데이터베이스에 새 값을 저장한다.
    repository.save(todo);
    log.warn("여기 들어오나?");
}

https://mangkyu.tistory.com/70

 

[Java] Optional이란? Optional 개념 및 사용법 - (1/2)

이번에는 Java8부터 지원하는 Optional 클래스에 대해 알아보도록 하겠습니다. 1. Optional이란? Optional 개념 및 사용법 [ NPE(NullPointerException) ] 개발을 할 때 가장 많이 발생하는 예외 중 하나가 바로 N..

mangkyu.tistory.com

 

return TodoEntity.builder().id(dto.getId()).title(dto.getTitle()).done(dto.isDone()).build();

빌더 패턴

https://mangkyu.tistory.com/163

 

[Java] 빌더 패턴(Builder Pattern)을 사용해야 하는 이유

객체를 생성하기 위해서는 생성자 패턴, 정적 메소드 패턴, 수정자 패턴, 빌더 패턴 등을 사용할 수 있습니다. 개인적으로 객체를 생성할 때에는 반드시 빌더 패턴을 사용해야 한다고 생각하는

mangkyu.tistory.com

 

@RequestBody

보통 반환하고자 하는 리소스가 복잡할 때 사용한다. 오브젝트처럼 복잡한 자료형을 통째로 요청에 보내고 싶은 경우 사용한다.

@GetMapping("/testRequestBody")
public String testControllerRequestBody(@RequestBody TestRequestBodyDTO testRequestBodyDTO){
    return "Hello World! ID " + testRequestBodyDTO.getId() + " Message : " + testRequestBodyDTO.getMessage();
}

 

@RestController는 @Controller + @ResponseBody로 구성되어있다.

@Controller는 @Component로 스프링이 이 클래스의 오브젝트를 알아서 생성하고 다른 오브젝트들과의 의존성을 연결한다는 뜻이다. @ResponseBody는 이 클래스의 메서드가 리턴하는 것은 웹 서비스의 ResponseBody라는 뜻이다.

메서드가 리턴할 때 스프링은 리턴된 오브젝트를 JSON의 형태로 바꾸고 HttpResponse에 담아 반환한다는 뜻이다.

@GetMapping("/testResponseBody")
public ResponseDTO<String> testControllerResponseBody() {
    List<String> list = new ArrayList<>();
    list.add("Hello World! I'm ResponseDTO");
    ResponseDTO<String> responseDTO = ResponseDTO.<String>builder().data(list).build();
    return  responseDTO;
}

 

ResponseEntity는 HTTP 응답의 바디뿐만 아니라 여러 다른 매개변수들(status, header)을 조작하고 싶을 때 사용한다.

package com.example.demo.dto;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.List;

@Builder
@NoArgsConstructor
@AllArgsConstructor
@Data
public class ResponseDTO<T> {
    private String error;
    private List<T> data;
}
@GetMapping("/testResponseEntity")
public ResponseEntity<?> testControllerResponseEntity(){
    List<String> list = new ArrayList<>();
    list.add("Hello World! I'm ResponseEntity. And you got 400!");
    ResponseDTO<String> responseDTO = ResponseDTO.<String>builder().data(list).build();
    // http status를 400으로 설정
    //return ResponseEntity.badRequest().body(responseDTO);

    // http status를 200으로 설정
    return ResponseEntity.ok().body(responseDTO);
}

 

서비스 레이어: 비즈니스 로직

서비스 레이어는 컨트롤러와 퍼시스턴스 사이에서 비즈니스 로직을 수행하는 역할을 한다.

@service 어노테이션

스테레오타입 어노테이션이다. @service 내부에는 @Component 어노테이션을 갖고 있는데 @Component 어노테이션과 비교했을 때 특별한 기능차이는 없다. 단지 이 클래스는 스프링 컴포넌트이며 기능적으로는 비즈니스 로직을 수행하는 서비스 레이어임을 알려주는 어노테이션이다.

package com.example.demo.service;

import org.springframework.stereotype.Service;

@Service
public class TodoService {

    public String testService(){
        return "Test Service";
    }
}
package com.example.demo.controller;

import com.example.demo.dto.ResponseDTO;
import com.example.demo.service.TodoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;

@RestController
@RequestMapping("todo")
public class TodoController {
    // testTodo 메서드 작성하기

    @Autowired
    private TodoService todoService;

    @GetMapping("/test")
    public ResponseEntity<?> TestTodo() {
        String str = todoService.testService(); // 테스트 서비스 사용
        List<String> list = new ArrayList<>();
        list.add(str);
        ResponseDTO<String> response = ResponseDTO.<String>builder().data(list).build();
        return ResponseEntity.ok().body(response);
    }
}

 

@RestController도 내부에 @Component 어노테이션을 갖고 있다. 따라서 @Service, @RestController 모두 자바 빈이고 스프링이 관리한다. 스프링은 TodoControlle 오브젝트를 생성할 때 내부에 선언된 TodoService에 @Autowired 어노테이션이 붙어있다는 것을 확인한다. @Autowired가 알아서 빈을 찾은 다음 그 빈을 이 인스턴스 멤버 변수에 연결하라는 뜻이다.

TodoController를 초기화할 때 스프링은 알아서 TodoService를 초기화 또는 검색해 TodoController에 주입해 준다.

레이어드 아키텍처 패턴

스프링 프로젝트 내부에서 어떻게 코드를 적절히 분리하고 관리할 것이냐에 대한 것

 

REST 아키텍처 스타일

클라이언트(브라우저)가  우리 서비스를 이용하려면 어떤 형식으로 요청을 보내고 응답을 받는지에 대한 것

Rest 아키텍처 스타일을 따라 설계 및 구현된 서비스를 RESTful 서비스라고 한다.

 

보통 자바로 된 비즈니스 애플리케이션의 클래스는 두 가지 종류로 나눌 수 있다

1. 일을 하는 클래스 = 기능을 수행하는 클래스(컨트롤러, 서비스, 퍼시스턴스)

2. 데이터를 담는 클래스 (엔티티, 모델, DTO)

 

롬복 어노테이션 설명

@Builder

Builder 클래스를 따로 개발하지 않고도 Builder 패턴을 사용해 오브젝트를 생성할 수 있다.

생성자를 이용해 오브젝트를 생성하는 것과 비슷하다. 생성자 매개변수의 순서를 기억할 필요가 없다.

사용방법

TodoEntity todoEntity = TodoEntity.builder()
        .id("id-11")
        .userId("developer")
        .title("게시물")
        .build();

 

@NoArgsConstructor

매개변수가 없는 생성자를 구현해 준다.

 

@AllArgsConstructor

클래스의 모든 멤버 변수를 매개변수로 받는 생성자를 구현해 준다.

 

@Data

클래스 멤버 변수의 Getter/Setter 메서드를 구현해 준다.

 

DTO

사용이유

1. 비즈니스 로직을 캡슐화 하기 위해

2. 클라이언트가 필요한 정보를 모델이 전부 포함하지 않는 경우가 많기 때문에

 

REST API

REST 아키텍처 스타일은 6가지 제약조건으로 구성된다. 이 가이드 라인을 따르는 API를 RESTful API라고 한다.

REST 제약조건

1. 클라이언트 - 서버

2. 상태가 없는

3. 캐시되는 데이터

4. 일관적인 인터페이스

5. 레이어 시스템

6. 코드-온-디맨드 (선택사항)

 

클라이언트 - 서버

리소스를 관리하는 서버가 존재하고 다수의 클라이언트가 리소스를 소비하려고 네트워크를 통해 서버에 접근하는 구조

리소스: REST API가 리턴할 수 있는 모든 것(HTML, JSON ..)

 

상태가 없음

클라이언트가 서버에 요청을 보낼 때 이전 요청의 영향을 받지 않음을 의미

HTTP는 기본적으로 상태가 없는 프로토콜이다.

 

캐시되는 데이터

서버에서 리소스를 리턴할 때 캐시가 가능한지 아닌지 명시할 수 있어야 한다.

HTTP에서는 cache-control이라는 헤더에 리소스의 캐시 여부를 명시할 수 있다.

 

일관적인 인터페이스

시스템 또는 애플리케이션의 리소스에 접근할 때 인터페이스가 일관적이어야 한다.

리소스에 접근하는 방식, 요청 형식 그리고 응답 형식 즉 URI 요청의 형태와 응답의 형태가 애플리케이션 전반에 걸쳐 일관적이어야 한다는 것이 일관적인 인터페이스 방침이다.

 

레이어 시스템

클라이언트가 서버에 요청을 할 때 여러 개의 레이어로 된 서버를 거칠 수 있다.

(인증 서버 - 캐싱 서버 - 로드 밸런서)

클라이언트는 서버의 레이어 존재 유무를 알지 못한다.

 

코드-온-디맨드(선택 사항)

클라이언트는 서버에 코드를 요청할 수 있고 서버가 리턴한 코드를 실행할 수 있다.

 

스프링 부트 스타터 웹의 어노테이션을 이용하면 연결을 쉽게 할 수 있다.

 

@RestController: 현재 컨트롤러가 RestController임을 명시한다.

RestController를 이용하면 http와 관련된 코드 및 요청/응답 매핑을 스프링이 알아서 해준다.

 

@GetMapping: 클라이언트가 이 리소스에 대해 Get 메서드로 요청하면 @GetMapping에 연결된 컨트롤러가 실행된다.

 

@PathVariable: /{id} 와 같이 URI의 경로로 넘어오는 값을 변수로 받을 수 있다.

 

@RequestParam: ?id={id}와 같이 요청 매개변수로 넘어오는 값을 변수로 받을 수 있다.

롬복 라이브러리를 이용하면 더 이상 getter, setter, builder, constructor를 작성하는데 시간을 소모할 필요가 없다.

 

이클립스에서 롬복을 사용하려면 jar 파일을 이용해 플러그인을 설치해야 한다.

 

https://mvnrepository.com/artifact/org.projectlombok/lombok

위 url에서 원하는 버전의 jar 파일을 다운 받는다.

 

파일을 받은 뒤 cmd 창을 이용하여 해당 경로로 이동 후 아래 명령어를 입력해 실행시킨다.

java -jar lombok-1.18.12.jar

 

명령어를 입력하면 lombok 프로그램이 실행되며 아래 표시 버튼을 클릭해서 계속 진행한다.

그 후 이클립스를 재시작해준다.

 

해당 프로젝트에서 롬복 어노테이션을 사용하기 위해 아래 순서대로 진행해준다.

아래 코드가 정상적으로 컴파일 되면 롬복 설치가 완료된것이다.

package com.example.demo;

import lombok.Builder;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;

@Builder
@RequiredArgsConstructor
public class DemoModel {

	@NonNull
	private String id;
}

 

스프링 부트 프로젝트 생성 사이트: Spring Initializr

 

이클립스에서 import시 반드시 gradle import로 진행 next 버튼 클릭후 Gradle wrapper를 선택한 후 계속 진행한다.

이 작업을 하는 이유는 사용자 PC에 gradle을 설치 하지 않았기 때문이다.

 

그 후 CMD 창에서 해당 프로젝트 폴더로 이동 후 명령어: gradlew bootRun 을 입력하면 동작한다.

 

 

확인

블로그 주소

삐멜 소프트웨어 엔지니어 - Happy Engineering! (cselabnotes.com)

 

삐멜 소프트웨어 엔지니어

Happy Engineering!

cselabnotes.com

 

 

github 소스 주소

fsoftwareengineer/todo-application (github.com)

 

GitHub - fsoftwareengineer/todo-application

Contribute to fsoftwareengineer/todo-application development by creating an account on GitHub.

github.com

 

책 관련 질문과 오류

Discussions · fsoftwareengineer/todo-application (github.com)

 

GitHub - fsoftwareengineer/todo-application

Contribute to fsoftwareengineer/todo-application development by creating an account on GitHub.

github.com

 

주니어 개발자를 위한 책이며

React, Spring boot, AWS 를 배우며 프론트엔드와 백엔드가 분리된 아키텍처를 경험해 보고 싶거나 아이디어가 있는데 어떻게 서비스를 만들어야 할지 모를 때 이 책을 읽으면 좋다고 되어있다.

 

구체적으로 프론트엔드는 대중화된 React.js를 이용해 개발하고 백엔드는 엔터프라이즈 애플리케이션 구현에 많이 사용하는 스프링 부트를 이용한다.

TODO 애플리케이션의 기본적인 기능을 구현한 후, 인증 기능을 추가해 다수의 사용자를 지원할 예정이다.

백엔드에서는 기존의 인증 방법의 스케일적 한계와 JWT를 이용해 스케일의 한계를 극복하는 방법을, 

프론트엔드에서는 로그인 상태를 유지하는 방법에 대해 알아보고 직접 구현할 예정이다.

그 후 만든 애플리케이션을 AWS에 배포한다.

배포 시 단순히 몇 개의 인스턴스에 애플리케이션을 배포하고 자동으로 할당되는 주소를 사용하는 게 아니라 로드밸런서, 오토스케일링그룹 등 스케일링에 필요한 서비스를 사용하고 도메인을 구매하고 HTTPS를 위한 인증서를 발급받아 설치하는 작업까지 할 예정이다.

 

이 책에서 다루는 내용

- REST 백엔드, React 프론트 엔드, AWS를 이용한 간단한 Todo 애플리케이션 개발

- 스프링 부트, 그래들, 메이븐 리포지터리, 롬복, JPA 등 REST API 개발에 필요한 내용 설명

- React.js의 원리와 프론트엔드 개발에 필요한 기초 지식 설명

- React.js와 같은 싱글 페이지 애플리케이션의 동작 방식 설명

- JWT를 이용한 인증 이론과 구현을 충실히 설명

- AWS 일라스틱 빈스톡을 이용해 애플리케이션을 배포하는 방법 및 배포 시 사용되는 EC2, 오토 스케일링 그룹, 로드 밸런서, RDS 등의 리소스 설명

- Route 53에서 DNS를 등록하는 방법과 DNS를 로드 밸런서로 연결하는 방법 설명

 

이 책은 커맨드라인 인터페이스를 많이 이용한다고 한다. 애플리케이션을 실행하거나 디렉터리를 만들거나 디플로이를 하는 경우에도 CLI를 이용한다고 한다.

그 이유는 CLI는 운영체제 의존성이 낮고 윈도우 버전 업그레이드를 신경 쓰지 않아도 되기 때문이다.

 

+ Recent posts