[postgreSQL] post request(express)을 통한 DATA ADD와 server side error 처리 (*cf. express-handlebars)

Hyo Kyun Lee·2021년 9월 7일
0

postgreSQL

목록 보기
5/6

1. (remind) express-handlebars 기본 구조

express-handlebars를 통해 각 page에 대한 middleware(간접접근경로) 생성 :
쉽게 말하면 router, data binding 등의 과정을 express-handlebars 문법으로 제어한다.

기본적으로 express-handlebars는 HTML template를 화면에 구성하는 view engine을 사용한다.

Home 화면을 제외한 나머지 page(router 요청)에 대해 express-handlebars 기능이 적용된다.

app.engine('handlebars', exphbs({defaultLayout: 'main'}))
app.set('view engine', 'handlebars')

먼저 view engine을 express에 구성해준다.

  • apollo가 graphql을 wrap하듯이, 그 원리와 비슷하다고 생각하면 된다.
  • handlebar는 정해져있는 구조대로 디렉토리를 구성해야 한다(views/layouts).
  • layouts를 통한 뼈대와 render하는 부분을 body로 구성하며, defaultlayout과 뼈대가 다를 경우(사용자 지정) 별도로 지정해주어야 한다.

2. post request를 통한 data 제출

data 정의 및 저장을 get요청이 아닌, 사용자 입력과 post요청을 통해 받도록 구성한다.

별도의 페이지로 이동하여(url get), post request를 통해 data를 제출하는 구조

2-1. post request 구성

//post request by ADD is on /tables/add url.
router.get('/add', (req,res)=> res.render('add'))

//DATA ADD by post request
router.post('/add', (req, res) => {
    //data add(by get request)
    const data = {
        title: 'WANTED FOR CPP DEVELOPER',
        technologies: 'REACT, JAVA, JAVA SCRIPT',
        budget: '$90000',
        description: 'SPECIFIC COMPANY A',
        contact_email: 'COMPANY_A@gmail.com'
    }
  • get request를 통해 별도의 페이지(url : '~/add')를 구성한다.
  • 이후 post 요청을 통해 data를 전달하는 logic을 구성한다.
  • ※위 구조는 add.handlebars를 통해 body 부분이 화면에 구현되고, 기본 handlebars로 main.handlebars(default layout)을 사용하는 구조이다.

2-2. body-parser 구성

post request에 대해, res인자의(request가 성공하였을때 받는 promise인자) body에 post request를 parsing할 수 있도록 구성한다.

const bodyParser = require('body-parser')

//body-parser for post request by form.
app.use(bodyParser.urlencoded({ extended: false }))

2-3. handlebars(template)에서의 action 구성

handlebars 내부적으로 action, action trigger(method)를 구성하여 준다.

<form action="/tables/add" method="POST">
        <div class="input-group">
          <label for="title">Title</label>
          <input type="text" name="title" id="title" class="input-box" placeholder="eg. Small Wordpress website, React developer"
            maxlength="100" value={{title}}>
        </div>
  • 전체 상위 tag인 form의 속성(attribute)에 action(url)과 method(post request)를 추가하여 준다.
  • 각 input의 value는 이후 body-parser를 통해 저장할 변수와 매칭하여 해당 입력값들을 저장하여 준다.

2-4. body-parsing logic 구성

앞에서 구성한 body-parser을 통해 req.body와 handlebars의 입력값들의 연결이 가능.

  • 위에서 기술한대로 handlebars의 변수와 body-parser를 통해 받는 변수를 서로 연결하여 준다.
router.post('/add', (req, res) => {

//could parse data by post by bodyparser configuration in app.js
//destructuring data
let {title, technologies, budget, description, contact_email} = req.body
  • 마찬가지로 받아온 데이터들은 req.body를 통해 parsing하여 준다.
  • parsing한 데이터들은 비구조화를 통해 받아온다.

2-5. data 제출

비구조화한 data들을 전달받아, 최종적으로 postgresql table로 제출한다.

//not any issues
    //ADD data to table information
    Model.create({
        title: title,
        technologies: technologies,
        budget: budget,
        description: description,
        contact_email: contact_email
    })
  • postgresql table에 data를 add하는 API는 table.create(*logic 내에서 정의한 postgresql table)이다.

2-6. data 제출여부 확인(화면/log/postgreSQL server cross check)

화면 확인

log 확인

postgresql server 내 data 축적 확인

3. server side에서의 error 처리 logic 구성

error 처리 logic을 server side에서 구성한다.

여기서 말하는 error는 submit 전의 공란발생의 경우를 말한다.

공란이 발생하였을 경우 현재 페이지로 re-rendering 되면서 error 메시지가 화면에 출력되도록 구성한다.

3-1. server side logic 개념

기본적으로 client 측에서 발생할 수 있는 모든 경우를 server 측이 고려한다.

  • 발생가능한 error(위에서 기술한 공란 발생 등)에 따른 탄력적인 처리가 가능하며
  • error 발생이 하지 않도록 유도하는 장치가 server 단에서 마련하도록 한다.

3-2. post request 구성(template/javascript logic)

template (post request와 연결하기 위한 구조 구성)

<form action="/tables/add" method="POST">
        <div class="input-group">
          <label for="title">Title</label>
          <input type="text" name="title" id="title" class="input-box" placeholder="eg. Small Wordpress website, React developer"
            maxlength="100" value={{title}}>
        </div>
  • 사용자가 입력을 할 수 있는 input tag 부분의 상위 tag를 form으로 구성하여 준다.
  • form tag의 action과 method를 각각 url, post request로 기재한다.

java script logic 구성(*post 요청 시 error 분기처리)

//DATA ADD by post request
router.post('/add', (req, res) => {

//could parse data by post by bodyparser configuration in app.js
//destructuring data
let {title, technologies, budget, description, contact_email} = req.body

//server side logic
//not adding required on input attribute,
//but log errors and inform clients to write values.
let errors = []

//Validate fields in server side
if(!title){
    errors.push({text: 'Please add title'})
}
if(!technologies){
    errors.push({text: 'Please add technologies'})
}
if(!description){
    errors.push({text: 'Please add description'})
}
if(!contact_email){
    errors.push({text: 'Please add contact_email'})
}

//seperate logic if errors occur or not.
if(errors.length > 0){
    //if anything issued
    res.render('add', {
        errors,
        title,
        technologies,
        budget,
        description,
        contact_email
    })
}else{
    //not any issues
    //ADD data to table information
    Model.create({
        title: title,
        technologies: technologies,
        budget: budget,
        description: description,
        contact_email: contact_email
    })
.then(list => res.redirect('/tables'))
.catch(err=>console.error('ERROR FOUND ', err))
}

})

template level에서 post request가 작동된 후 logic은 다음과 같이 실행한다.

  • error 발생 시(사용자가 input을 입력하지 않은 공란 발생 등)
    → 공란 발생 시 error 배열에 error message를 저장한다.
    → 그 후 error 배열을 체크하고, error 발생에 대한 모든 인자(error 배열을 포함한 사용자가 입력한 모든 input 값까지)는 다시 re-rendering 하면서 전달해준다.
  • error 없을 경우
    → 정상적으로 table에 data가 저장되고, 이에 따른 화면구현 / redirect 작동한다.

3-3. error 체크 후 re-rendering (in handlebars)

handlebars - #each를 활용하여 error 배열 내부의 객체들을 화면에 구현하도록 구성.

{{#each errors}}
        <div class="error">
          <p>{{text}}</p>
        </div>
      {{/each}}
  • {{#each erros}} 내부의 객체는 text로 구현하였다.
  • 중괄호를 두번 사용하여({{}}), 해당 text를 바로 화면에 구현할 수 있게 되었다.

re-rendering 하면서 errors, title, ..과 같은 인자를 비구조화하여 그대로 활용할 수 있다.

<input type="text" name="title" id="title" class="input-box" placeholder="eg. Small Wordpress website, React developer"
            maxlength="100" value={{title}}>
  • value = {{title}}

3-4. 화면 확인

  • 아래 공란을 두었을때, 원래 화면 상태에서 error messgae가 출력되었다.
  • 사용자 측에서 발생하는 issue 사항을 sever 측에서 자동적으로 고려하였고, 이를 server side logic으로 구현하였다.

4. issue logic

server side에서 처리하는 issue logic을 구성한다.

여기서 발생하는 issue는

  • budget 부분(특정 변수)에 대해 required(필수 항목)은 아니지만, 관리자 측에서 받는 form을 일괄된 형식으로 받기 위한 작업이다.
  • technologies 변수의 경우 콤마이후의 여백을 공백없이/소문자 전환 등으로 처리하는 작업까지 포함한다.

4-1. javscript logic 추가

 //budget variable would be given with dollar sign.
    //and budget is not required, also it would be controlled.
    if(!budget){
        budget = 'UNKNOWN'
    }else{
        budget = `$${budget}`
    }

    //technologies variable would be given with lowercase
    //and space after comma is going to be removed.
    technologies = technologies.toLowerCase().replace(/, /g, ',')
  • javscript logic을 추가하고, issue를 처리하는 작업을 진행한다.

4-2. 화면 구현 확인

위 issue에 대한 logic이 정상작동하는지 확인한다.

  • budget, technologies에 대한 처리가 올바르게 작동하는지 테스트한다.

화면 확인

  • 화면에 관리자가 확인하기 용이한 form으로 출력되었는지 확인한다.

postgresql table 확인

  • 동일한 구조로 postgresql table에 data가 저장되었는지 확인한다.

5. 참조링크

Build a Node.js App With Sequelize [3] - Add
https://www.youtube.com/watch?v=6jbrWF3BWM0

body-parser urlencoded option
https://stackoverflow.com/questions/55558402/what-is-the-meaning-of-bodyparser-urlencoded-extended-true-and-bodypar

bodyParser.urlencoded 관련
https://sjh836.tistory.com/154

tag - required
http://tcpschool.com/html-tag-attrs/input-required

0개의 댓글