The Web Developer - (Udemy)_ 미들웨어 : Express 의 키(key)

‍정진철·2022년 8월 8일
0

web devloper (udemy)

목록 보기
16/34

1) Express 미들웨어 개요

미들웨어는 body를 파싱할 때 사용

  • Express middleware are functions that run during the request/response lifecycle.

  • 내장 JSON 미들웨어를 이용해 request.body를 파싱함.

  • 또한 Express 정적 미들웨어로 CSS, 이미지, javascript와 같은 정적파일도 처리.

  • 미들웨어는 Express 내 모든 것 중 하나의 구성 요소일 뿐.

  • 요청-응답 생명주기 내에서 실행되는 함수.

  • 즉, Express에 요청이 전달되는 순간부터 코드가 처리를 완료하고 응답을 내보낼 때 까지 실행.

MIDDLEWARE

  • Middleware are just functions.
  • Each middleware has access to the request and response objects.
  • Middleware can end the HTTP request by sending back a response with methods like res.send()
  • OR middleware can be chained together, one after another by calling next()

2) 모건-로거 (Morgan - Logger) 미들웨어 사용하기

Mogran

  • HTTP 요청을 터미널에 로그로 넘겨 줌. (디버깅 시 유용)
  • 모든 요청을 기록할 수 있게됨.
  • app.use로 가져오기. (모든 요청에 코드를 가져다줌).
<index.js>


const express = require('express');
const app = express();
const morgan = require('morgan');

morgan('tiny')


app.use(
    morgan('tiny'))


app.get('/', (req,res)=> {
    res.send('home page')
})

app.get('/dogs', (req,res)=> {
    console.log('WOOFFFF!!!')
})

app.listen(3000, () => {
    console.log('App is running on localhost:3000')
})


2) 미들웨어 정의하기

localhost:3000/dogs 로 진입시 미들웨어 실행.

  • 세번째 인자로 'next' 를 사용해 다음의 미들웨어나 라우트 핸들러를 실행함.
  • next 밑에는 통상적으로 다른 코드 기입 X (return 값으로 마무리.)


3) 미들웨어 연습 더 알아보기

  • method(GET) 와 해당경로(/dogs)가 출력됨.


  • method 를 'GET'으로 설정해놓으니 postman에서 요청을 'POST'로 하여도 'WOOFFF!!!'의 GET 메소드가 실행됨.
  • app.use를 다른 라우트 핸들러보다 상위에 적어줬기 때문에 그런것.
    (순서중요)


  • app.use에서 요청객체에 대한 requsetTime을 설정해줌으로써 모든 모든 라우트 핸들러에서 reuquestTime에 접근가능해짐.
  • app.use가 먼저 실행되므로 (정의 위치 중요)
    - app.use가 다른 라우트 핸들로보다 밑에 존재하면 실행 X


4) 404 경로 설정

위 app.use 중 어떠한 라우트핸들러들의 주기도 종료되거나 매칭되지 않을 때 가장 아래에 존재하는 app.use는 어떤 요청에도 매칭이되니 '찾을수없음'이 뜨게됨.


  • 보통 오류페이지 같은 경우 오류 코드(404)까지 같이 입력해줌.


5) 미들웨어 패스워드 설정 데모

  • query에 해당하는 부분이 ?food=chicken


쿼리 비밀번호 설정

password 쿼리 제대로 입력시 /dogs 라우트 핸들러 발동.

password 쿼리가 입력되지 않았을 때 오류발생.


6) 특정 경로 보호하기

app.use 대신 함수로 설정 (콜백함수로 사용하기 위함)

/secret 경로에만 적용되는 verifyPassword 콜백함수 등록

  • secret 라우트로 들어가기위해서 ?password=chickennugget 입력 필요.


7) Layouts를 위한 새로운 EJS 툴

npm i ejs.mate

  • layout
    -> 상용구 정의 가능.
    -> 상용구를 통해 컨텐츠 사이에 코드 삽입 가능.

<app.js>
//ejs.mate 사용하겠다고 알리기.
const ejsMate = require('ejs-mate')
app.engine('ejs', ejsMate)

8) 부트스트랩5! 상용구 코드

campgrounds 폴더에 있는 ejs 파일에 일괄적으로 적용시킬 수 있는 layouts(boilerplate(상용구)파일 생성))


campgrounds폴더에 있는 모든 ejs 파일에 일괄적으로 boilerplate.js 파일 적용시키기.

  • <% layout('layouts/boilderplate')%>


9) 내비게이션 바 부분

공통적으로 적용되는 부분들을 한 파일에 모아 언제든지 가져다 쓸 수 있게 만들기.

<navbar.ejs>

<nav class="navbar sticky-top navbar-expand-lg navbar-dark bg-dark">
  <div class="container-fluid">
    <a class="navbar-brand" href="#">YelpCamp</a>
    <button
      class="navbar-toggler"
      type="button"
      data-bs-toggle="collapse"
      data-bs-target="#navbarNavAltMarkup"
      aria-controls="navbarNavAltMarkup"
      aria-expanded="false"
      aria-label="Toggle navigation"
    >
      <span class="navbar-toggler-icon"></span>
    </button>
    <div class="collapse navbar-collapse" id="navbarNavAltMarkup">
      <div class="navbar-nav">
        <a class="nav-link" href="/">Home</a>
        <a class="nav-link" href="/campgrounds">Campgrounds</a>
        <a class="nav-link" href="/campgrounds/new">New Campground</a>
      </div>
    </div>
  </div>
</nav>
  • boilerplate 파일에 적용시킴으로써 campgrounds 폴더의 ejs 파일 (라우트 이동 파일들)들에게도 일괄적으로 적용 가능.


10) footer 부분

<footer.ejs>

<!-- py-3 : padding을 y축방향(상단)으로 주는것-->
<footer class="footer bg-dark py-3 mt-auto">
  <div class="container">
    <!-- text-muted: 텍스트 약간 밝고 부드럽게 만들기-->
    <!-- &copy; : 저작권 문양 넣기-->
    <span class="text-muted">&copy; YelpCamp2022 </span>
  </div>
</footer>

////

<boilerplate.ejs>
  <!-- d-flex: display flex, flex-column: body의 방향성이 세로로 길게 향하게 그래야 footer가 하단에 깔림 -->
  <!-- bootstrap 을 활용중이므로 css 설정 가능.-->
  <!-- body가 flexbox이어서 상단부터 하단까지 위치한 열이다.
     line에는 가로축을 따라 움직이는 self가 있어 모든게 가로축상에 놓여짐. 또 item이라는것도 있어 모든게 왼쪽에서 오른쪽으로
     정렬됨. 따라서 justify-content 사용시 모든 항목들에게 영향을 끼치게됨. 그러나
     footer 처럼 메인항목 하나만 움직이게 만들어주고 싶은거기 때문에
    상단여백(mt-auto), 좌측여백(ml-auto)를 사용.-->
 <body class="d-flex flex-column vh-100">
    <%- include('../partials/navbar')%>
    <main class="container mt-5">
          <%- body %>
    </main>
    <%- include('../partials/footer')%>

11) 이미지 추가하기

Unplash Source (무료로 사용가능한 고화질 이미지)

1) models 폴더 내 campground.js 파일에 image 정보 추가

const CampgroundSchema = new Schema({
    title: String,
    image:  String,
    price: Number,
    description: String,
    location: String
});

2) seeds 폴더 내 index.js 파일에 Campground 모델에 정보 추가

const seedDB = async() => {
    //기존의 캠핑장은 삭제.
    await Campground.deleteMany({});
    //랜덤으로 캠핑장 50개 리스트 만들기.
    for(let i=0; i<50; i++) {
       const random1000 = Math.floor(Math.random() * 1000);
       const price =Math.floor(Math.randon() * 20) + 10; 
        // 캠프 객체들 생성하기.
        const camp = new Campground({
            location : `${cities[random1000].city}`,
            state : `${cities[random1000].state}`,
            //' 아름다운 캐년'처럼 형용사 + 명사 조합
            title: `${sample(descriptors)} ${sample(places)}`,
            image:  'https://source.unsplash.com/collection/483251',
            description: 'Lorem ipsum, dolor sit amet consectetur adipisicing elit. Sint cum eos sed saepe, totam quo eaque maiores voluptatem mollitia aliquid? Ea consequatur cum repudiandae, totam pariatur voluptatem quia nesciunt ipsam!',
            price

            
        })
        //50개 캠핑장 저장.
        await camp.save();

3) campgrounds 폴더 내 show.ejs 파일에 img,description 추가

<show.ejs>


<% layout('layouts/boilerplate')%>

    <h1><%=campground.title%></h1>
    <h2><%=campground.location%></h2>
    <img src="<%=campground.image%>" alt="">
    <p><%=campground.description%></p>
    <p>
      <a href="/campgrounds">All Campgrounds</a>
    </p>
    <p>
      <form action="/campgrounds/<%=campground._id%>?_method=DELETE" method="POST">
        <button>Delete</button>
      </form>
    </p>
    <footer>
      <a href="/campgrounds/<%=campground._id%>/edit">Edit Campground</a>
    </footer>

12) 캠프그라운드 인덱스 스타일링

/campgrounds/index

<index.ejs>
<% layout('layouts/boilerplate')%>
<h1>All Campgrounds</h1>
<a href="/campgrounds/new">Add Campground</a>
<ul>
  <% for (let campground of campgrounds){%>
  <li>
    <div class="card" mb-3>
      <div class="row">
        <!-- img 삽입 1/3 차지-->
        <div class="col-md-4">
          <img class="img-fluid" alt="" src="<%=campground.image%>" />
        </div>
        <!-- 캠핑장에 대한 제목과 설명 부분 2/3 차지-->
        <div class="col-md-8">
          <div class="card-body">
            <h5 class="title"><%=campground.title%></h5>
            <p class="card-text"><%=campground.description%></p>
            <p class="card-text">
              <samll class="text-muted"><%=campground.location%></samll>
            </p>
            <a class="btn btn-primary" href="/campgrounds/<%=campground._id%>"
              >View <%=campground.title%></a
            >
          </div>
        </div>
      </div>
    </div>
  </li>
  <% }%>
</ul>

13) 새로운 양식 스타일링

new.ejs

  • 각각의 항목마다 div를 걸고 mb-3 을 줌
  • css 파일 추가시키는것보다 부트스트랩 클래스이용.
<% layout('layouts/boilerplate')%>
<div class="row">
  <h1 class="text-center">New Campground</h1>
  <!-- 열의 절반을 차지하되 왼쪽으로 쏠리지 않고 가운데로 오게끔 3만큼 ㅇffset 시키는것.-->
  <div class="col-6 offset-3">
    <form action="/campgrounds" method="POST">
      <!-- mb-3 : css 파일을 따로 만드는것보다 부트스트랩 클래스를 이용하는것이 더 효율적-->
      <div class="mb-3">
        <label class="form-label" for="title">Title</label>
        <!-- campground[title]처럼 중괄호사이에 이름이나 위치등을 넣으면 데이터가 POST 요쳥을 해서 
          Express 앱을 지나 서버로 갈 때 <body>에 포함된게 campground라고 정렬됨.
              콘텐츠를 그룹화 할 수 있는 좋은 방법.-->
        <input
          class="form-control"
          type="text"
          id="title"
          name="campground[title]"
        />
      </div>
      <div class="mb-3">
        <label class="form-label" for="location">Location</label>
        <input
          class="form-control"
          type="text"
          id="location"
          name="campground[location]]"
        />
      </div>
      <div class="mb-3">
        <label class="form-label" for="image">Image URL</label>
        <!-- campground[title]처럼 중괄호사이에 이름이나 위치등을 넣으면 데이터가 POST 요쳥을 해서 
          Express 앱을 지나 서버로 갈 때 <body>에 포함된게 campground라고 정렬됨.
              콘텐츠를 그룹화 할 수 있는 좋은 방법.-->
        <input
          class="form-control"
          type="text"
          id="image"
          name="campground[image]"
        />
      </div>
      <div class="mb-3">
        <label class="form-label" for="price">Campground Price</label>
        <div class="input-group">
          <span class="input-group-text">$</span>
          <input
            type="text"
            class="form-control"
            aria-label="price"
            id="price"
            placeholder="0"
            name="campground[price]"
          />
          <span class="input-group-text">.00</span>
        </div>
      </div>
      <div class="mb-3">
        <label class="form-label" for="description">Description</label>
        <!-- campground[title]처럼 중괄호사이에 이름이나 위치등을 넣으면 데이터가 POST 요쳥을 해서 
          Express 앱을 지나 서버로 갈 때 <body>에 포함된게 campground라고 정렬됨.
              콘텐츠를 그룹화 할 수 있는 좋은 방법.-->
        <textarea
          class="form-control"
          type="text"
          id="description"
          name="campground[description]"
        >
        </textarea>
      </div>
      <div class="div mb-3">
        <button class="btn btn-primary">Submit</button>
      </div>
    </form>
    <a href="/campgrounds">All Campgrounds</a>
  </div>
</div>

14) 편집 양식 스타일링

show.ejs

<% layout('layouts/boilerplate')%>
<div class="row">
  <h1 class="text-center">Edit Campground</h1>
  <!-- 열의 절반을 차지하되 왼쪽으로 쏠리지 않고 가운데로 오게끔 3만큼 ㅇffset 시키는것.-->
  <div class="col-6 offset-3">
    <form action="/campgrounds/<%=campground._id%>?_method=PUT" method="POST">
      <!-- mb-3 : css 파일을 따로 만드는것보다 부트스트랩 클래스를 이용하는것이 더 효율적-->
      <div class="mb-3">
        <label class="form-label" for="title">Title</label>
        <!-- campground[title]처럼 중괄호사이에 이름이나 위치등을 넣으면 데이터가 POST 요쳥을 해서 
          Express 앱을 지나 서버로 갈 때 <body>에 포함된게 campground라고 정렬됨.
              콘텐츠를 그룹화 할 수 있는 좋은 방법.-->
        <input
          class="form-control"
          type="text"
          id="title"
          name="campground[title]"
          value="<%=campground.title %>"
        />
      </div>
      <div class="mb-3">
        <label class="form-label" for="location">Location</label>
        <input
          class="form-control"
          type="text"
          id="location"
          name="campground[location]]"
          value="<%=
    campground.location%>"
        />
      </div>
      <div class="mb-3">
        <label class="form-label" for="image">Image URL</label>
        <!-- campground[title]처럼 중괄호사이에 이름이나 위치등을 넣으면 데이터가 POST 요쳥을 해서 
          Express 앱을 지나 서버로 갈 때 <body>에 포함된게 campground라고 정렬됨.
              콘텐츠를 그룹화 할 수 있는 좋은 방법.-->
        <input
          class="form-control"
          type="text"
          id="image"
          name="campground[image]"
          value="<%=
    campground.image%>"
        />
      </div>
      <div class="mb-3">
        <label class="form-label" for="price">Campground Price</label>
        <div class="input-group">
          <span class="input-group-text">$</span>
          <input
            type="text"
            class="form-control"
            aria-label="price"
            id="price"
            placeholder="0"
            name="campground[price]"
            value="<%=campground.pirce%>"
          />
          <span class="input-group-text">.00</span>
        </div>
      </div>
      <div class="mb-3">
        <label class="form-label" for="description">Description</label>
        <!-- campground[title]처럼 중괄호사이에 이름이나 위치등을 넣으면 데이터가 POST 요쳥을 해서 
          Express 앱을 지나 서버로 갈 때 <body>에 포함된게 campground라고 정렬됨.
              콘텐츠를 그룹화 할 수 있는 좋은 방법.-->
        <textarea
          class="form-control"
          type="text"
          id="description"
          name="campground[description]"
        >
          <%=campground.description%>
        </textarea>
      </div>
      <div class="div mb-3">
        <button class="btn btn-primary">Submit</button>
      </div>
    </form>
    <a href="/campgrounds/<%=campground._id%>">Back to Campgrounds</a>
  </div>
</div>

15) 쇼 페이지 스타일링

show.ejs

<% layout('layouts/boilerplate')%>
<div class="row">
  <div class="col-6 offset-3">
    <div class="card mb-3">
      <img src="<%=campground.image%>" class="card-img-top" alt="..." />
      <div class="card-body">
        <h5 class="card-title"><%=campground.title%></h5>
        <p class="card-text"><%=campground.description%></p>
      </div>
      <ul class="list-group list-group-flush">
        <li class="list-group-item text-muted"><%=campground.location%></li>
        <li class="list-group-item">$<%= campground.price%>/night</li>
      </ul>
      <div class="card-body">
        <a
          class="card-link btn btn-primary"
          href="/campgrounds/<%=campground._id%>/edit"
          >Edit</a
        >
        <form
          class="d-inline"
          action="/campgrounds/<%=campground._id%>?_method=DELETE"
          method="POST"
        >
          <button class="btn btn-danger">Delete</button>
        </form>
      </div>
    </div>
  </div>
</div>

profile
WILL is ALL

0개의 댓글