최근 웹 애플리케이션 개발에서는 프론트엔드와 백엔드를 분리하는 방식이 많이 사용되고 있습니다. 프론트엔드 프레임워크로는 Angular, React, Vue.js 등이 인기를 끌고 있죠. 여기서는 Spring 기반의 백엔드를 프론트엔드 프레임워크와 효과적으로 통합하는 방법에 대해 알아보겠습니다.
REST API를 통한 통신
프론트엔드와 백엔드를 연결하는 가장 일반적인 방법은 REST API를 사용하는 것입니다. 백엔드에서 REST 엔드포인트를 제공하고, 프론트엔드에서는 이를 호출하여 데이터를 주고받는 방식입니다.
Spring에서 REST API 구현
@RestController
를 사용하여 컨트롤러 클래스 구현@GetMapping
,@PostMapping
등의 어노테이션으로 엔드포인트 매핑@RequestBody
,@PathVariable
등으로 요청 데이터 바인딩ResponseEntity
를 사용하여 응답 데이터와 상태 코드 반환
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
@RestController
@RequestMapping(“/api”)
public class UserController {
@Autowired
private UserService userService;
@GetMapping(“/users”)
public List<User> getAllUsers() {
return userService.findAll();
}
@PostMapping(“/users”)
public ResponseEntity<User> createUser(@RequestBody User user) {
User savedUser = userService.save(user);
return ResponseEntity.created(URI.create(“/api/users/” + savedUser.getId())).body(savedUser);
}
}
|
cs |
프론트엔드에서 API 호출
- Angular의 경우
HttpClient
, React의 경우axios
등의 HTTP 클라이언트 사용 - 서비스 클래스에서 API 호출 로직 캡슐화
- RxJS(Angular), Promise(React) 등을 사용하여 비동기 처리
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
// Angular
@Injectable({
providedIn: ‘root’
})
export class UserService {
private apiUrl = ‘http://localhost:8080/api/users’;
constructor(private http: HttpClient) { }
getUsers(): Observable<User[]> {
return this.http.get<User[]>(this.apiUrl);
}
createUser(user: User): Observable<User> {
return this.http.post<User>(this.apiUrl, user);
}
}
|
cs |
CORS 설정
프론트엔드와 백엔드를 별도의 도메인으로 배포할 경우, CORS(Cross-Origin Resource Sharing) 이슈가 발생할 수 있습니다. 이를 해결하기 위해서는 백엔드에서 CORS 설정을 해주어야 합니다.
Spring에서 CORS 설정
@CrossOrigin
어노테이션을 사용하여 컨트롤러 또는 메소드 단위로 설정WebMvcConfigurer
를 구현하여 글로벌 설정
1
2
3
4
5
6
|
@RestController
@RequestMapping(“/api”)
@CrossOrigin(origins = “http://localhost:4200”)
public class UserController {
// …
}
|
cs |
1
2
3
4
5
6
7
8
9
10
11
|
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping(“/api/**”)
.allowedOrigins(“http://localhost:4200”)
.allowedMethods(“GET”, “POST”, “PUT”, “DELETE”)
.allowCredentials(true);
}
}
|
cs |
프론트엔드에서 CORS 대응
- Angular의 경우
proxy.conf.json
파일 설정 - React의 경우
http-proxy-middleware
라이브러리 사용
1
2
3
4
5
6
7
|
// Angular – proxy.conf.json
{
“/api”: {
“target”: “http://localhost:8080”,
“secure”: false
}
}
|
cs |
웹소켓을 사용한 실시간 통신
실시간 데이터 전송이 필요한 경우 웹소켓을 사용할 수 있습니다. Spring에서는 STOMP를 지원하여 손쉽게 웹소켓 통신을 구현할 수 있습니다.
Spring에서 웹소켓 구현
@EnableWebSocketMessageBroker
어노테이션으로 웹소켓 활성화@MessageMapping
으로 메시지 처리 엔드포인트 매핑@SendTo
,@SendToUser
등으로 메시지 전송
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.enableSimpleBroker(“/topic”);
registry.setApplicationDestinationPrefixes(“/app”);
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint(“/ws”).setAllowedOrigins(“http://localhost:4200”).withSockJS();
}
}
|
cs |
1
2
3
4
5
6
7
8
9
|
@Controller
public class ChatController {
@MessageMapping(“/chat”)
@SendTo(“/topic/messages”)
public ChatMessage send(ChatMessage message) throws Exception {
return new ChatMessage(message.getFrom(), message.getText(), new Date());
}
}
|
cs |
프론트엔드에서 웹소켓 연결
- Angular의 경우
stompjs
,sockjs-client
라이브러리 사용 - React의 경우
@stomp/stompjs
,sockjs-client
라이브러리 사용
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
// Angular
import * as Stomp from ‘stompjs’;
import * as SockJS from ‘sockjs-client’;
// …
const socket = new SockJS(‘http://localhost:8080/ws’);
const stompClient = Stomp.over(socket);
stompClient.connect({}, (frame) => {
console.log(‘Connected: ‘ + frame);
stompClient.subscribe(‘/topic/messages’, (message) => {
console.log(message.body);
});
});
stompClient.send(“/app/chat”, {}, JSON.stringify({ from: ‘user’, text: ‘hello’ }));
|
cs |
지금까지 Spring 백엔드와 Angular/React 프론트엔드를 통합하는 방법에 대해 알아보았습니다. REST API를 통한 HTTP 통신이 기본이 되고, 필요에 따라 CORS 설정이나 웹소켓을 활용할 수 있습니다.
프론트엔드와 백엔드의 역할을 명확히 분리하고, 느슨한 결합을 유지하는 것이 중요합니다. 이를 위해 API 설계에 신경써야겠죠. 또한 인증/인가 처리나 데이터 유효성 검증 등도 고려해야 할 부분입니다.
Angular, React 등의 프론트엔드 프레임워크는 꾸준히 발전하고 있습니다. 백엔드 개발자도 프론트엔드 생태계의 변화를 잘 따라가면서, 효율적인 협업 방안을 모색해 나가는 것이 좋겠습니다.