반응형

이전에 팀프로젝트로 만든 파일을  로컬에서만 쓰다가 오늘 호스팅 하는 방법을 배워서

호스팅 하는 방법을 올려보려고 한다.

 

리액트파일과 서버파일이 있어서 두곳에 따로따로 호스팅 해줘야 한다. 

 

Node.js 서버 호스팅

HEROKU

https://dashboard.heroku.com/apps

 

Heroku

 

dashboard.heroku.com

위의 사이트에 들어가서 가입을 해줘야한다.

가입을 하면 로그인을 하고 create new app으로 들어가 준다

 

이제 여기서 이름을 설정해 주고 Create app을 누르면 깃허브리포지터리 같은 게 만들어진다.

 

만들고 나면 이런 창으로 이동하게 되는데 깃허브처럼 파일을 여기로 보내주면 된다

heroku로 push 하기 위해서는 heroku를 설치해줘야 한다. 

https://devcenter.heroku.com/articles/heroku-cli

 

The Heroku CLI | Heroku Dev Center

Last updated January 17, 2023 The Heroku Command Line Interface (CLI) lets you create and manage Heroku apps directly from the terminal. It’s an essential part of using Heroku. Install the Heroku CLI Pre-requisites The Heroku CLI requires Git, the popula

devcenter.heroku.com

링크로 들어가서 해당하는 운영체제와 옵션에 따라 설치해주면 된다.

 

설치하면 이제 호스팅 할준비가 끝났다 호스팅할 파일들도 준비를 좀 해줘 야한다

 

1. 호스팅 할 서버 파일이름을 index.js로 변경 

2. 호스팅 하는 파일의 port번호 변경

const port = process.env.PORT || 8080;
//지정해주는 포트번호가있다면 지정번호를사용하고 없다면 8080포트 사용

3.package.json 변경

 

 "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "node index.js"
  },

 

이렇게 해준 뒤에 이제 깃허브에 push 하는 것과 똑같이 해주면 된다 

cmd 나 터미널을 이용해 주자

서버폴더위치에서 입력해줘야 한다.

 

주의사항*

서버를 깃허브에서 클론 해온 경우 node.module이 설치되어 있는지 확인 

없다면 npm install로 설치

 

. git 폴더를 지우고 처음부터 git init 하기 

 

업로드 전 서버를 실행시켜 보고 잘 실행되는지 확인!

 

json의 scripts.start 부분이 서버의 파일이름과 일치하는지 확인!!!

 

 

터미널에 입력

$ cd 프로젝트 위치
$ git init
$ git add .
$ git commit -m "heroku deploy" //커밋은 넣고싶은메모를 넣으면된다
$ heroku git:remote -a app name //이부분은 deploy에 쓰여있으니 복붙!
 --> 예시 $ heroku git:remote -a zzang9ha

$ git push heroku main //현재브랜치이름을 넣어주자 브랜치변경을 하지않았다면 master일수도 있다

 

push 까지 해 주고 오른쪽상단에 있는 open App을 눌러서 이런 창이 뜨면 성공이다 다른 에러창이 뜬다면 

json파일과 포트번호 그리고 모듈들이 잘 설치되어 있는지 다시 확인해 보고 리포지터리를 삭제한 다음 다시 만들어서 호스팅을 시도해야 한다..

 

서버의 데이터를 요청하는 주소로 이동하니 데이터를 잘 보내주는 걸 볼 수 있다! 이제 서버 끝 

 

 

React.js 호스팅

 

Vercel 가입하기

 

https://vercel.com/

 

Vercel: Develop. Preview. Ship. For the best frontend teams

Vercel is the platform for frontend developers, providing the speed and reliability innovators need to create at the moment of inspiration.

vercel.com

위 사이트를 통해서 github를 연결해서 바로 호스팅 할 수 있다.

깃허브로 회원가입이 가능하니 깃허브로 가입하고 빠르게 진행할 수 있다.

 

vercel에 리액트 파일을 호스팅 하기 전에 리액트 파일의 서버주소를

호스팅 된 노드서버주소로 변경해 준 다음 npm start로 실행해 보자.

리액트프로젝트의 서버주소 변경

나는 서버주소를 apiurl.js에서 변수로 선언해서 사용하고 있어서 여기 주소만 변경해 주겠다. 뒤에 / 가 필요하면 붙여주고 필요 없으면 때 주면 된다 서버에 요청을 어떻게 하는지 확인하자.

 

이제 다시 vecel로 돌아가서 

 

Add new에 project를 클릭하고 들어가서

깃허브를 연결해 주고 호스팅 하고 싶은 파일을 import 해주면 된다.

이제 이 화면에서 Deploy 해주고 기다리면 호스팅이 끝난다.

 

여기서는 수정할 부분이 있으면 로컬파일을 수정해서 다시 깃허브에 push 해주면

vercel에서 다시 호스팅 해준다.

 

https://team-project-thenadlee.vercel.app/

 

React App

 

team-project-thenadlee.vercel.app

호스팅 된 팀프로젝트.

반응형
반응형

화장품을 파는 쇼핑몰 사이트를 만들어보자!!

메인페이지, 상품페이지, 상품업로드 페이지를 만들고 각 페이지는 폴더를 따로 만들어서 저장한다.

컴포넌트폴더를 만들고  HeaderFooter (상단화면 하단화면)을 만들어 준다.

메인페이지에 들어갈 상품태그도 컴포넌트로 만들어서 컴포넌트 폴더에 넣어주겠다.

 

코드샌드박스로 코드를 올릴 텐데 서버는 에러가뜨고 로컬에 있는 mysql이랑 어떻게 연결하는지 몰라서 리액트만 코드샌드박스로 올리고 서버와 mysql연결하는 부분은 코드로 올리겠다..

 

우선 headerfooter main page를 만들어준다

 

Header.js /Header.css

import React from 'react';
import { Link } from 'react-router-dom';
import './Header.css';
const Header = () => {
    return (
        <div className='header'>
            <h1><Link to='/'>Cosmeticsv</Link></h1>
            <ul>
            <li>스킨케어</li>
            <li>메이크업</li>
            <li><Link to='/upload'>제품등록</Link></li>
            </ul>
        </div>
    );
};
export default Header;

-----------------------------------------------------------------------------------------------

Header.css
a{
    text-decoration: none;
    color: inherit;
}
.header{
    display: flex;
    width: 100%;
    max-width: 1200px;
    padding: 20px;
    justify-content: space-between;
    margin: 0 auto;
}
.header ul{
    display: flex;
}
.header li{ padding:0 20px; list-style: none; }

Header에서는 제목을 클릭하면 메인화면으로 빠져나갈 수 있게 Link를 넣어주었고 제품등록을 클릭하면 제품등록창으로 이동할 수 있게 Link를 넣어주었다.

 

Footer.js /Footer.js

import React from 'react';
import './Footer.css'

const Footer = () => {
    return (
        <div className='footer'>
            <div className='info'>
                <div className='inner'>
                    <div >
                        <h2>무통장입금계좌</h2>
                        <div>
                            <p>BANK ACCOUNT</p>
                            <p>301-1234-5678-01</p>
                            <p>예금주 - 김혜라</p>
                        </div>
                    </div>
                    <div>
                        <h2>고객센터</h2>
                        <div>
                            <p>영업시간 이외에는 문의 게시판을 이용해주시면 당담자 확인 후 빠른 답변 도와드리겠습니다.</p>
                            <p>02-1263-1245</p>
                        </div>
                    </div>
                    <div>
                        <h2>공지사항</h2>
                        <ul>
                            <li>조명가이드 2022-06-20</li>
                            <li>신상품 입고 안내 2022-06-10</li>
                            <li>몰 오픈을 축하드립니다. 2022-02-20</li>
                        </ul>
                    </div>
                </div>
            </div>
            <div className='footermenu'>
                <div className='inner'>
                    <ul>
                        <li>홈</li>
                        <li>매장안내</li>
                        <li>이용약관</li>
                        <li>개인정보처리방침</li>
                    </ul>
                </div>
            </div>
            <div className='address'>
                <div className='inner'>
                상호 :  주소 : 울산광역시 남구 어딘가 대표전화 : 국번없이 123-456-7891 대표이사 : 김OO 개인정보관리자 : 이OO 사업자 등록번호 : 102-12-12345 copyright(c) Greck Lamp,.LTD all rights reserved.
                </div>
            </div>
        </div>
    );
};

export default Footer;
----------------------------------------------------------------------------------------------------------------------
Footer.css

.footer {
    margin-top: 60px;
    text-align: left;
}
.info{
    border-top:3px solid #333;
    border-bottom:1px solid #333;
    padding: 20px 0;
}
.inner{
    width:100%;
    max-width:1200px;
    margin: 0 auto;
}
.info .inner{
    display: flex;
    justify-content: space-between;
}
.info .inner > div{
    width: 32%;
    padding-bottom:20px ;
    line-height: 1.8;
}
.info .inner h2{
    border-bottom: 1px solid #ccc;
    line-height: 50px;
    font-size: 20px;
}

.info .inner > div div{
    padding:20px 0 ;
}
.info .inner > div ul {
    padding: 20px 0;
}
.footermenu ul{
    display: flex;
    height:60px;
    align-items: center;
}
.footermenu ul li{
    padding: 0 20px;
    border-right: 1px solid #ccc;
}
.footermenu ul li:last-child{
    border-right:none;
}
.address{
    border-top:1px solid #ccc;
    background-color: #eee;
    padding: 30px 0;
}

 

Footer는 좀 긴데 일반 사이트처럼 별로 기능은 들어간게없고 그냥 정보를 알려주는 용도이다. 

 

ProductList.js

import React from 'react';
import { Link } from 'react-router-dom';

const ProductList = ({p_id,p_price,p_name}) => {
    return (
        <li>
            <Link to={`/detailView/${p_id}`}>
                <img src={`../images/cosmetic${p_id}.JPG`} alt="" />
                <h3>{p_name}</h3>
                <p>{p_price}원</p>
                <p>간단한 설명입니다.</p>
            </Link>
        </li>
    );
};

export default ProductList;

ProductList는 메인페이지 의 ul태그에 넣어줄 컴포넌트이다 같은 li태그 구조가 반복되기 때문에

컴포넌트로 만들고 달라지는 이미지와 상품명 가격은 props로 받아서 넣어준다.

 

HeaderFootercomponents폴더에 넣어서 보관해준다.

 

index.js / index.css (src/main폴더)

import React from 'react';
import { Link } from 'react-router-dom';
import ProductList from '../components/ProductList';
import './index.css';

const data=[ //이 데이터를 서버에서 받아올거임
	{
		p_id:"1",
    	p_name:"상품1",
        p_price:"10000",
    },
    {
		p_id:"2",
    	p_name:"상품2",
        p_price:"20000",
    },
    {
		p_id:"3",
    	p_name:"상품3",
        p_price:"30000",
    },
    {
		p_id:"4",
    	p_name:"상품4",
        p_price:"40000",
    },
]

const MainPage = () => {    
    return (
        <div className='main'>
            <div className='visual'>
                <img src ="images/banner1.jpg" alt="배너이미지1"/> 
            </div>
            <div className='product'>
                <h2>신상품</h2>
                <ul>
                    {data.map(pro=>
                    <ProductList key={pro.p_id} p_id={pro.p_id} p_name={pro.p_name} p_price={pro.p_price}/>)}
                </ul>
            </div>
        </div>
    );
};

export default MainPage;

----------------------------------------------------------------------------------------------------------
index.css

.visual img{
    width: 100%;
}
.product{
    width:100%;
    max-width: 1200px;
    margin: 0 auto;
}
.product h2{
    padding-bottom:40px
}
.product ul {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
}
.product ul li{
    width:25%;
    /* border: 1px solid #ddd; */
    padding-bottom: 20px;
}
.product ul li img{
    width: 100%;
}
.product ul li h3{
    padding: 10px;
}
.product ul li p {
    padding: 0 10px;
}

 

 

원래 mainpage에 들어갈 이미지는 mysql에서 받아와야 하는데 코드샌드박스로는 할 수 없기 때문에

data 객체 를 따로 코드 안에 만들어 주었다. 

 

이제 상품이미지를 클릭했을 때 상품상세화면으로 들어가게 해 주겠다. 

ProductList.js에서 이미지를 클릭할 때 이동할 링크를 '/detailView/${p_id}'로 줬기 때문에

App에서도 <Route path = '/detailView/:p_id' element=(<ProductPage/>)/>를 넣어서 받아준다

function App() {
  return (
    <div className="App">
      <Header/>
      <Routes>
        <Route path='/' element={<MainPage/>}/>
        <Route path='/detailView/:p_id' element={<ProductPage/>}/>
      </Routes>
      <Footer/>
    </div>
  );
}

 

이제 ProductPage를 만들어보자

 

index.js /index.css (src / product폴더)

import React from 'react';
import { useParams } from 'react-router-dom';
import './index.css'

const ProductPage = () => {
    const {p_id} = useParams();

    return (
        <div className='productDetail'>
            <h2>기초스킨케어 세트</h2>
            <div className='productImg'>
                <img src={`../images/cosmetic${p_id}.JPG`} alt="" />
            </div>
            <div>
                <p>스킨케어 주간 베스트</p>
                <p>헤라 스킨</p>
                <p>가격 : 65,000</p>
                <p>무료배송</p>
            </div>
        </div>
    );
};

export default ProductPage;
-------------------------------------------------------------------------------------------------

.productDetail{
    margin: 0 auto;
    width:100%;
    max-width: 1200px;
}
.productDetail h2{
    padding-top: 30px;
    padding-bottom: 30px;
}
.productImg{
    text-align: center;
}
.productImg img{
    border-radius:50% ;
}

ProductPage에서는 ProductLists에서 Link에  /detailView/${p_id}를 넣어준 것을

useParams( )로 객체로 받아서 값을 

p_id에 할당해 주고 이미지 src를 설정하는 데 사용한다.

 

상품을 추가해 주는 upload페이지도 만들어 보겠다.

 

index.js/index.css (src / upload폴더)

import React from 'react';
import './index.css'

const UploadPage = () => {
    return (
        <div className='upload'>
            <h2>제품등록하기</h2>
            <form>
                <table>
                    <thead></thead>
                    <tbody>
                    <tr>
                        <td>상품사진</td>
                        <td>
                            <input type="file" name="p_img" />
                            
                        </td>
                    </tr>
                    <tr>
                        <td>상품이름</td>
                        <td>
                            <input type="text" name="p_name" />
                            
                        </td>
                    </tr>
                    <tr>
                        <td>상품소개</td>
                        <td>
                            <input type="text" name="p_info" />
                            
                        </td>
                    </tr>
                    <tr>
                        <td>상품가격</td>
                        <td>
                            <input type="number" name="p_price" />
                            
                        </td>
                    </tr>
                    <tr>
                        <td>상품수량</td>
                        <td>
                            <input type="number" name="p_quantity" />
                        </td>
                    </tr>
                    <tr>
                        <td>상세설명</td>
                        <td>
                            <textarea name="p_desc" ></textarea>
                        </td>
                    </tr>
                    <tr>
                        <td colSpan={2}>
                            <button type='submit'>등록</button>
                            <button>취소</button>
                        </td>
                    </tr>
                   </tbody>
                    <tfoot></tfoot>
                </table>
            </form>
        </div>
    );
};

export default UploadPage ;

------------------------------------------------------------------------------------------------

.upload{
    margin: 40px auto;
    width: 100%;
    max-width:1200px;
}
.upload h2{
    font-size: 24px;
    padding-bottom:20px;
}
.upload table{
    border-collapse: collapse;
    width: 100%;
}
.upload td{
    border-bottom: 1px solid #ccc;
    padding: 16px;
}
.upload td:nth-child(1){
    width:20%;
}
.upload input[type='text'], .upload textarea{
    width:100%;
}

upload페이지는 아직 형태만 만들어놓고 아무 기능도 추가하지 않았다

나중에는 추가했을 때 서버로 데이터가 전송되도록 해줄 것 같다.

upload페이지로 이동하는 주소는 Header에서  <Linkto='/upload'> 제품등록 </Link>으로 주고 있다. 

 

App.js 

import './App.css';
import Header from './components/Header';
import Footer from './components/Footer';
import MainPage from './main';
import ProductPage from './product';
import { Routes,Route } from 'react-router-dom';
import UploadPage from './upload';

function App() {
  return (
    <div className="App">
      <Header/>
      <Routes>
        <Route path='/' element={<MainPage/>}/>
        <Route path='/detailView/:p_id' element={<ProductPage/>}/>
        <Route path='/upload' element={<UploadPage></UploadPage>}/>
      </Routes>
      <Footer/>
    </div>
  );
}

export default App;

App에서 일치하는 경로에 따라 Route들을 렌더링 해주고 있다. 

 

 

 

 

데이터를 서버에서 받아오기

 

서버코드

//express 서버 만들기
const express = require("express");//import express
const cors = require("cors");

//mysql부르기
const mysql = require("mysql");

//서버 생성 --> express( )호출
const app = express();
//프로세서의 주소 포트번호 지정
const port = 8080;
// JSON형식의 데이터를 처리할수 있도록 설정
app.use(express.json());
// 브라우저의 CORS 이슈를 막기 위해 사용하는 코드
app.use(cors());

//sql 연결선 만들기
const conn = mysql.createConnection({
    host:"localhost",
    port:'3306',
    user:"root",
    password:"1234",
    database:"shopping"
})
//sql 연결하기 
conn.connect();



// get요청시 응답 app.get(경로,콜백함수)
app.get('/products',(req,res)=>{
    conn.query('select * from products',function(error,result,fields){
        res.send(result);
    });
})


//서버구동
app.listen(port,()=>{
    console.log("서버가 돌아가고있습니다.")
})

(서버실행방법: 터미널에 node 서버이름.js 입력) 

서버에서 로컬에 있는 데이터베이스에 접근해서 데이터를 가져와서 응답으로 보내준다.

 

서버에서 보내주는 값은 사이트에서 axios로 받아온다

 

커스텀훅 

useAsync.js

import React, { useEffect, useReducer } from 'react';
//1.상태초기화
const initialState = {
    loading:false,
    data:null,
    error:null,
}
//2.리듀서 함수구현
//로딩중일때 상태
//데이터를 성공적으로 받았을때 상태
//에러일때 상태
function reducer(state,action){
    switch(action.type){
        case "LOADING":
            return{
                loading:true,
                data:null,
                error:null,
            }
        case "SUCCESS":
            return{
                loading:false,
                data:action.data,
                error:null,
            }
        case "ERROR":
            return{
                loading:false,
                data:null,
                error:action.error,
            }
        default:
            return state;
    }
}


const useAsync = (callback,deps=[]) => {
    const [state,dispatch] = useReducer(reducer,initialState);
    //데이터 요청 함수
    const fetchData = async ()=>{
        //로딩의 value를 true로 업데이트
        dispatch({
            type:"LOADING"
        });
        // try catch 에러 처리 구문 ,,데이터를 요청하는 과정은 에러발생할 확률이 높음
        try{
            //axios에서 받는 함수가 들어감 useAsync를 사용하는 컴포넌트에서 각각 다른 주소를 넣어서 보내줌
            const data = await callback(); 
            dispatch({
                type:"SUCCESS",
                data  //data : data 인데 같으니까 생략가능함
            })
        }
        catch(e){
            dispatch({
                type:"ERROR",
                error:e
            })
        }
    }
    useEffect(()=>{
        fetchData();
    },deps)
    return state;
};

export default useAsync;

데이터를 받았을 때 상태를 바꿔주는 커스텀 훅을 만들어주고 

 

main.js

import axios from 'axios';
import React from 'react';
import { Link } from 'react-router-dom';
import ProductList from '../components/ProductList';
import useAsync from '../customHook/useAsync'
import './index.css';

async function productFetch(){
    const response = await axios.get("http://localhost:8080/products");
    return response.data
}

const MainPage = () => {
    const state = useAsync(productFetch,[])
    const{loading,error,data}=state;
    if (loading) return <div>로딩중</div>
    if (error) return <div>에러발생</div>
    if (!data) return null
    console.log(data)
    return (
        <div className='main'>
            <div className='visual'>
                <img src ="images/banner1.jpg" alt="배너이미지1"/>
            </div>
            <div className='product'>
                <h2>신상품</h2>
                <ul>
                    {data.map(pro=>
                    <ProductList key={pro.p_id} p_id={pro.p_id} p_name={pro.p_name} p_price={pro.p_price}/>)}
                </ul>
            </div>
        </div>
    );
};

export default MainPage;

메인화면에서 useAsync를 import 해서 사용 useAsync에 파라미터로 입력한 주소의 데이터를 얻어서

리턴해주는 함수와 빈 배열을 넣어준다. 이렇게 넣어주면 useAsync의 콜백함수로 들어가서

주소에서 받아온 데이터가 data상태값에 들어가게 되고 useAsync에서 반환해 주는 state값을

Mainpage에서 받아서 이용할 수 있게 된다.

 

 

 

 

 

반응형
반응형

노드서버 만들기


브라우저가 아닌 곳에서도 node.js를 이용하면 javascript 를 실행할 수 있다.
노드에서는 모듈을 로딩하는 방법에서 차이가 있다 import 대신 require 사용

 

모듈로딩

es6 방식

export functuin Hello( ){ }
import Hello from './Hello.js'

common js 방식

function hello( ){ }
module.export = hello;
const hello = require('/hello.js')

 

서버를 만들어줄 폴더를 생성 
생성한 폴더에서 npm init으로 노드를 초기화해 준다.
RestAPI [post, get,] 데이터를 어떻게 받아오고 보낼지 만드는 것

 

프로토콜://호스트주소:포트번호/경로? 쿼리
http://localhost:8080/product? name=item

 

http: 80 포트번호가 생략
https :433 포트번호가 생략

Server.js

//node는 common JS를 사용함
//불러올때 require를 사용
const http = require('http');
//본인 컴퓨터 주소를 의미함!!
const hostname = "127.0.0.1"; //localhost
const port = 8080; //포트번호
//createServer() --> 서버생성
//요청정보 req, 응답정보 res
const server = http.createServer(function(req,res){
    const path = req.url;
    const method = req.method;
    if(path==="/products"){ //주소가 /products일때
        //응답을 보낼때 json 객체를 보낼거임
        res.writeHead(200,{'Content-type':'application/json'})//json파일을 다룰수있게해줌
        //객체를 json파일 로 변환 JSON.stringify(obj)
        const product = JSON.stringify({
            name:"기초화장품",
            price:50000
        })
        res.end(product); //응답을 보내줌 .end( )
    }else{
        res.end('hahahahahahahahah');
    }
})

//listen은 대기 호스트네임과 포트 번호 요청을 기다림
server.listen(port,hostname); //서버를 응답할수잇도록 대기상태로 만듬.
console.log("화장품 서버가 동작 중입니다.") //서버를 시작했을때 터미널에 뜨는문자

이렇게 넣어주고 node 파일이름 을 터미널에 입력해 주면 서버가 실행된다.

서버가 실행되면 해당주소인 http://localhost:8080에 들어가면 접근할 수 있고

path조건에 /product를 달아놔서 http://localhost:8080/products로 들어가면 JSON객체가 뜨게 되고

그 외 에는 'hahahaha'가 뜨는 창으로 이동한다.

 

지금은 좌표를 /product로 지정해 놔서 바로 JSON객체를 보여준다 hahaha가 뜨는 걸 보고 싶으면

open Sandbox버튼을 누르고 들어가서 주소에서/products를 지워주면 hahaha가 보인다.

기본좌표 화면

 

이게 서버를 만드는 방법인데 설정해 줄 것도 많고

불편해서 보통은 express라는 라이브러리 프레임워크를 쓴다고 한다.

 

Express프레임워크

npm install express
npm install cors

 

index.js

//express 서버 만들기
const express = require("express");//import express
const cors = require("cors"); //import cors


//서버 생성 --> express( )호출
const app = express(); 
//프로세서의 주소 포트번호 지정
const port = 8080;
// JSON형식의 데이터를 처리할수 있도록 설정
app.use(express.json());
// 브라우저의 CORS 이슈를 막기 위해 사용하는 코드
app.use(cors());




// get요청시 응답 app.get(경로,콜백함수)
app.get('/',(req,res)=>{ //기본경로 
        res.send([ //클라이언트에게 응답을 보내줌
            {
                id:"1",
                name:"제품1",
                price:"10000"
            },
            {
                id:"2",
                name:"제품2",
                price:"20000"
            },
            {
                id:"3",
                name:"제품3",
                price:"30000"
            },
            {
                id:"4",
                name:"제품4",
                price:"40000"
            }
        ])
});

app.get("/products/:id",(req,res)=>{
    const params = req.params; //주소창에서보내주는 파라미터를 받아줌 {id:입력한값}
    const {id} = params;
    res.send(`id는${id}이다`)
})

//서버구동
app.listen(port,()=>{ //서버대기
    console.log("서버가 돌아가고있습니다.")
})

node index.js로 서버실행(터미널에 입력)

이번코드는 샌드박스에서 컴파일이 안되고 에러가 떠서 비주얼스튜디오로 해서

실행화면만 캡처했다.(왜 안될까..)

 

JSON객체를 반환

 

똑같이 입력하고 서버를 실행하면 나랑 똑같은 화면이 안 나올 수도 있는데 나는 JSONView라는

크롬 확장프로그램을 써서 보기 편하게 해 두었다. 확장프로그램이 없다면 한 줄로 쭈욱 나올 듯..

(크롬 웹스토어에 들어가서 검색하면 설치할수있다!)

 

URL파라미터 받기 (params)

서버에서도 url에 입력된 파라미터를 받아줄 수 있다. 

app.get("/products/:id",(req,res)=>{
    const params = req.params; //주소창에서보내주는 파라미터를 받아줌 {id:입력한값}
    const {id} = params;
    res.send(`id는${id}이다`)
})

params를 받아주는 구문이다 /products 뒤에 파라미터가 담기면 id키로 받고

값은 req에 있는 params에 저장된다.

req.params로 객체를 받아서 id에 구조분해할당을 해주는 구문이다.

 

req를 console.log로 콘솔에 띄워보면 아래 그림처럼 값들이 나온다

 

req.params

products/1로 접속하면 위 사진처럼 params에 값이 나온다.

 

express서버에서  mysql 연동

 

1.database 설계

1) create database shopping
2) crate table products( )
3) insert문으로 데이터 생성

 

예제 테이블

 

데이터베이스 생성

create database shopping

use shopping

테이블 생성

create table products(
     p_id int primary key auto_increment,
     p_name varchar(20) not null,
     p_price int not null,
     p_desc text ,
     p_quantity int not null,
     p_img varchar(100)
)

데이터삽입

insert into products(p_name, p_price, p_desc, p_quantity, p_img)
values("기초스킨케어 1",50000, "인기 있는 상품입니다.",80, "images/cosmetic1.JPG");
insert into products(p_name, p_price, p_desc, p_quantity, p_img)
values("기초스킨케어 2",70000, "인기 있는 상품입니다.",50, "images/cosmetic2.JPG");
insert into products(p_name, p_price, p_desc, p_quantity, p_img)
values("기초스킨케어 3",40000, "인기 있는 상품입니다.",30, "images/cosmetic3.JPG");
insert into products(p_name, p_price, p_desc, p_quantity, p_img)
values("기초스킨케어 4",70000, "인기 있는 상품입니다.",60, "images/cosmetic4.JPG");

 

똑같이 입력해주면 아래와같은 데이터베이스 테이블이 하나 생성된다.

예제 테이블

2.express서버에 mysql설치

npm install mysql

 

1) mysql 라이브러리 불러오기 //const mysql = require("mysql");
2) mysql접속 생성 

mysql.createConnection({
	host:"localhost",
	user:"root",
	password:"1234",
	database:"shopping",
	port:"3306"
})


3) mysql 접속 conn.connect( )
4) 쿼리 전송

app.get('/products',(req,res)=>{
	conn.query(쿼리문,함수(error,result,field){ 
	res.send(result)
	})   // field=table의 컬럼이름
})

 

완성코드)

index.js

//express 서버 만들기
const express = require("express");//import express
const cors = require("cors");

//mysql import
const mysql = require("mysql");
//서버 생성 --> express( )호출
const app = express();
//프로세서의 주소 포트번호 지정
const port = 8080;
// JSON형식의 데이터를 처리할수 있도록 설정
app.use(express.json());
// 브라우저의 CORS 이슈를 막기 위해 사용하는 코드
app.use(cors());

//sql연결선
const conn = mysql.createConnection({
    host:"localhost",
    port:"3306",
    user:"root",
    password:"1234",
    database:"shopping"
})
//sql 연결하기
conn.connect()


// get요청시 응답 app.get(경로,콜백함수)
app.get('/products',(req,res)=>{
    conn.query('select * from products',function(error,result,field){
        if(error){
            res.send(error)
        }
        res.send(result);
        console.log(result);
    })    
});

app.get("/products/:id",(req,res)=>{
    const params = req.params;
    const {id} = params;
    res.send(`id는${id}이다`)
})

//서버구동
app.listen(port,()=>{
    console.log("서버가 돌아가고있습니다.")
})

아까 객체로 보내줬던 값을 이번에는 데이터베이스에서 조회해서 페이지로 전달해주고 있다.

배열에 데이터베이스에서 받아온 값들이 객체로 들어가서 전달된다.

sql을 받아서 출력한값

 

 

여기까지 기본서버와 express서버를 만들었고 url파라미터를 받는 방법과 mysql을 연결해서 데이터베이스를 받아오는 걸 공부해 봤다. 다음포스팅은 데이터베이스에서 받아온 데이터를 서버에 올려주고 서버에 올린 값을 리액트에서 axios로 받아서 이용하는 페이지를 만들어 보겠다. 

 

 

 

 

 

 

나는 프런트엔드 수업을 듣고 있어서 서버를 만드는 방법은 배웠지만 이 서버가 어떤 원리로 동작하고 어떤 코드가 정확하게 어떤 역할을 하는지는 간단한 설명만 듣고 넘어갔다. 아마 백엔드는 이것보다 배울게 많겠지.. 지금은 리액트를 하느라 바쁘지만 나중에 조금 시간이 생긴다면 서버에 대해서 조금 더 공부해보고 싶다.

반응형

+ Recent posts