[2] 음식점 포스 프로그램 - 개발 설정 : front, Back-End

2023. 9. 20. 00:50Github 프로젝트/음식점 포스 프로그램

728x90
반응형
SMALL

이번 시간은 Front-End (React)와 Back-End (Java/Spring Boot)  설정을 시작하겠습니다.

 

Github : https://github.com/BerkleyLim/foodstor_pos

 

GitHub - BerkleyLim/foodstor_pos: This is the program on foot store pos machine.

This is the program on foot store pos machine. . Contribute to BerkleyLim/foodstor_pos development by creating an account on GitHub.

github.com

 

이번 프로젝트는 TypeScript 기반의 프로젝트로 React-Query를 활용한 프론트엔드 개발을 진행을 하고,

Gradle 기반으로 H2 Database를 활용한 Spring Boot 개발을 진행 하겠습니다.

 

 

1. React 셋팅 (TypeScript 기반)

> 개발 환경 : nodejs 16.18.0

 

1) TypeScript 기반으로 프로젝트를 진행 시 아래와 같이 명령어 입력

npx create-react-app food-front --template typescript

 

 

2) 아래와 같이 라이브러리들 설치 (자세한건 npm 설치 방법은 별도로 설치해보자)

react-query, reactstrap, bootstrap, node-scss, node-sass, react-router, react-router-dom, recoil

 

 

3) 설치 완료된 모습

아래와 같이 typescript로 설치가 완료 되고, 마찬가지로 package.json에서 설치됨을 확인할 수 있습니다.

 

4) 이후 App.tsx에서 React-Query와 Recoil 을 아래와 같이 셋팅해줍니다.

import './App.css';
import {
  QueryClient,
  QueryClientProvider,
} from 'react-query'
import Index from './component/index';


const queryClient = new QueryClient();

const App = () => {
  return (
    <RecoilRoot>
      <QueryClientProvider client={queryClient}>
        <Index />
      </QueryClientProvider>
    </RecoilRoot>
  );
}


export default App;

 

Redux 대신에 Recoil로 클라이언트단의 상태 관리를 실시하고,

React-Query의 서버의 캐쉬 관리를 위해 사용할 것이다. 

주로 axios나 fetch로 외부 API를 불려오는데 쓰일 예정이다.

React Query 사용은 백엔드 설계 이후 연동 할때 설명한다.

 

 

5) 다음은 component 폴더를 생성하고, index.tsx에 React-router-dom을 넣어보자.

필자는 자주 쓰이는 것 위주로 넣어 보았다.

이 뜻은, 각각의 uri 의 따라 해당 컴포넌트가 추가 될 수 있음을 알린다.

import styles from "./index.module.scss"
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';
import InputUserInfo from './UserInfo/InputUserInfo';
import Bank from './bank/Bank';
import MenuIndex from './menu/MenuIndex';
import PosFood from './posfood/PosFood';

const Index = (): string | any => {
  return (
    <Router>
      <div className={`${styles?.componentContainer}`}>
        <Routes>
          <Route path="/" element={<InputUserInfo />} />
          <Route path="/inputuserinfo" element={<InputUserInfo />} />
          <Route path="/menuindex" element={<MenuIndex />} />
          <Route path="/posfood" element={<PosFood />} />
          <Route path="/bank" element={<Bank />} />
        </Routes>
      </div>
    </Router>
  )
}

export default Index

 

 

 

 

2. Spring 셋팅 (Gradle기반)

> 개발 환경 : Java 11

 

1) Spring Boot 셋팅한다 (자세한건 구글링 검색 및 게시판 프로젝트 참조)

 

2) 다음은 아래와 같이 환경 필수적으로 설정

JDBC, JPA, My-Batis, Lombok, Devtools, H2

 

<build.gradle에서 dependencies 설정 내용>

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-jdbc'
	implementation 'org.springframework.boot:spring-boot-starter-web'
	implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:2.3.1'
	implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
	compileOnly 'org.projectlombok:lombok'
	developmentOnly 'org.springframework.boot:spring-boot-devtools'
	runtimeOnly 'com.h2database:h2'
	annotationProcessor 'org.projectlombok:lombok'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
	testImplementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter-test:2.3.1'
}

 

3) My-Batis, H2를 연동하기 위해 properties.yaml 설정

spring:
  h2:
    console:
      enabled: true  # H2 Console을 사용할지 여부 (H2 Console은 H2 Database를 UI로 제공해주는 기능)
      path: /h2-console  # H2 Console의 Path
  datasource:
    driver-class-name: org.h2.Driver  # Database를 H2로 사용하겠다.
    # url: jdbc:h2:~/food-pos  # H2 접속 정보 (embeded 모드)
    url: jdbc:h2:mem:food-pos  # H2 접속 정보 (In-Memory 모드)
    username: sa  # H2 접속 시 입력할 username 정보 (원하는 것으로 입력)
    password:  # H2 접속 시 입력할 password 정보 (원하는 것으로 입력)
    hikari:
      data-source-properties:
        cachePrepStmts: true
        prepStmtCacheSize: 250 # 연결당 캐쉬가 준비할 명령문의 수 지정
        prepStmtCacheSqlLimit: 2048
        useServerPrepStmts: true # 서버측 준비된 명령문 지원, 성능 향상 도움됨
      connectionTimeout: 30000
      maximumPoolSize: 10
      max-lifetime: 1799995
      # minimum-idle: 1000
      # poolName : HikariCP
      readOnly : false
  devtools:
    liverload:
      enabled: true
  sql:
    init:
      encoding: UTF-8
      mode: always
      
 mybatis:
  type-aliases-package: com.berkley.food.store.pos.machine.foodback.domain.dto
  configuration:
    cache-enabled: true
    use-column-label: true
    use-generated-keys: false
    map-underscore-to-camel-case: true
    default-statement-timeout: 25000
    jdbc-type-for-null: NULL
  mapper-locations: classpath:/mapper/*Mapper.xml

 

4) resource 폴더에 data.sql과 schema.sql 에 아래와 같이 넣기

이 작업은 Spring Boot 실행 시 H2 Database에 Table과 데이터를 미리 넣고 H2 Console로 들어가면 추가 되어 있음을 확인 할 수 있습니다.

<schema.sql>

-- 테스트
DROP TABLE IF EXISTS t_test;

CREATE TABLE t_test COMMENT '회원'  (
  uno bigint not null auto_increment,
  test_field varchar(255),
  PRIMARY KEY (uno)
);

 

 

<data.sql>

insert into t_test (test_field) values ('테스트용');

 

 

 

5) H2 접속하여 schema 상태 확인

Properties.yaml 에서 h2.console.path 경로 설정한 내용 그대로 웹 브라우저 창 띄어서 접속해보기

필자는 "/h2-console" 로 설정 해두었기 때문에 http://localhost:8080/h2-console 로 접속하여 확인한다.

 

아래와 같이 접속 이후 스키마가 저장되어 있는지 확인 할 수 있다.

 

 

6) 이후 My-Batis 연동 되어 있는지 확인하고, 테스트 해본다.

먼저 Mapper.xml과 Mapper, Service, Controller 설정 후 PostMan API로 테스트 해보자.

 

- resource/mapper/FoodMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "//mybatis.org/DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.berkley.food.store.pos.machine.foodback.mapper.FoodMapper">
  <select id="testSQL" resultType="TestDto">
    select * from t_test
  </select>
</mapper>

 

- Mapper Class

package com.berkley.food.store.pos.machine.foodback.mapper;

import java.util.List;

import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;

import com.berkley.food.store.pos.machine.foodback.domain.dto.TestDto;

@Repository
@Mapper
public interface FoodMapper {
  List<TestDto> testSQL();
}

 

 

- Service Class

package com.berkley.food.store.pos.machine.foodback.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.berkley.food.store.pos.machine.foodback.domain.dto.TestDto;
import com.berkley.food.store.pos.machine.foodback.mapper.FoodMapper;

@Service
public class FoodService {
  @Autowired
  FoodMapper foodMapper;

  public List<TestDto> testSQL() {
    return foodMapper.testSQL();
  }
}

 

- Controller Class

package com.berkley.food.store.pos.machine.foodback.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.berkley.food.store.pos.machine.foodback.domain.dto.TestDto;
import com.berkley.food.store.pos.machine.foodback.service.FoodService;

@RestController
@RequestMapping("/api/food")
public class FoodController {
  @Autowired
  FoodService foodService;

  @GetMapping("/test")
  public List<TestDto> testSQL() {
    return foodService.testSQL();
  }
}

 

 

- Post Man Test 결과

 

3. Front(React) 서버와 Back(Java/Spring Boot) 서버간 통신하기

 

1) React 서버에서 App.tsx 에서 react-query를 활용하여 console.log 값을 출력해본다.

import React from 'react'
const { useState, useEffect } = React;

..
const Index = (): string | any => {

  const { isLoading, isError, data} = useQuery({
    queryKey: ['repoData'],
    queryFn: () => 
    fetch('http://localhost:8080/api/food/test').then(
      (res) => res.json(),
    ),
  });

  if (isLoading) return 'Loading...';

  if (isError) return 'An error has occurred : ';

  console.log(data)
  return (
  	......
  )
}

 

코드의 대한 설명은

isLoading 상태일 경우 : 로딩 중으로 표시 되며 Loading... 표시

isError 상태일 경우 : 인터페이스 연동 실패 시 An error has occurred :  표시

연동 성공시 : console.log에 출력 되며, 해당 데이터를 삽입 가능하다.

 

2) console.log() 결과 : CORS Error

아래는 CORS 정책의 의해 API 접근이 차단을 한다.

따라서, Java 서버에서 접근 허용 할 수 있도록 설정한다.

대개 "api/" 로 시작하는 경로를 이용하여 접근 할 수 있도록 한다.

 

 

3) Java/Spring Boot에서 CORS 문제 해결 방법

<Java/Spring Boot 에서 CORS 문제 해결해 주는 로직>

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class CorsConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry
                .addMapping("/api/**")
                .allowedOrigins("http://localhost:3000");
    }
}

 

 

4) React 서버에서 다시 호출 후 결과

 

 

 

여기까지 셋팅을 진행 해 보았습니다.

다음 시간에는 Page 제작 하는 방법의 대해 알아가겠습니다.

728x90
반응형
LIST