# 1. Express

키워드

* Express 란
* URL 구조
* REST API
* HTTP Method(CRUD)

## Express

Node.js 웹 애플리케이션 프레임워크

Node.js

* V8엔진으로 빌드된 자바스크립트 런타임
  * 런타임 : 특정 언어로 만든 프로그램을 실행할 수 있는 환경
* 다양한 자바스크립트 애플리케이션을 실행할 수 있게 해줌(주로 서버를 실행)

Express

* Node.js에서 효율적으로 웹 애플리케이션을 개발할 수 있도록 도와주는 프레임워크
* HTTP 유틸리티 메소드 및 미들웨어로 쉽고 빠르게 API를 작성할 수 있음

ts-node

.ts 파일을 따로 컴파일하지 않고 node.js에서 타입스크립트를 실행하는 도구

### Express 환경 설정

```bash
mkdir express-demo-app
cd mkdir express-demo-app
```

.gitignore 세팅

```bash
touch .gitignore
echo "/node_modules/" > .gitignore
```

패키지 초기화

```bash
npm init -y
```

TypeScript

```bash
npm i -D typescript
npx tsc --init
```

ESLint

```bash
npm i -D eslint
npx eslint --init
```

ts-node

```bash
npm init -y
```

Express 설치

```bash
npm i express
npm i -D @types/express
```

### Hello World 예제

app.ts `http://localhost:3000/`으로 GET요청이 들어오면 `Hello, world!`를 응답

```js
import express from 'express';

const port = 3000;

const app = express();

app.get('/', (req, res) => {
  res.send('Hello, world!');
});

app.listen(port, () => {
  console.log(`Server running at http://localhost:${port}`);
});
```

ts-node로 실행

```bash
npx ts-node app.ts
```

코드 수정시 자동으로 반영되도록 nodemon 사용

```bash
npm i -D nodemon
npx nodemon app.ts
```

package.json script 세팅

```js
  "scripts": {
    "start": "npx nodemon app.ts",
    "lint": "eslint --fix ."
  },
```

## REST API

* URI는 정보의 자원을 표현
  * `/write-post` 처럼 동작을 표현하지 않고 `/post` 처럼 자원만 명시
* 자원에 대한 행위는 HTTP Method로 표현(GET, POST, PUT, DELETE)
  * Collection(복수)과 Item(Element)(단수)로 나뉨
  * Read (Collection) → GET /products ⇒ 상품 목록 확인
  * Read (Item) → GET /products/{id} ⇒ 특정 상품 정보 확인
  * Create (Collection Pattern 활용) → POST /products ⇒ 상품 추가 (JSON 정보 함께 전달)
  * Update (Item) → PUT 또는 PATCH /products/{id} ⇒ 특정 상품 정보 변경 (JSON 정보 함께 전달)
  * Delete (Item) → DELETE /products/{id} ⇒ 특정 상품 삭제

### Thinking in React 예제

```js
app.get('/products', (req, res) => {

  const products = [
    {
      category: 'Fruits', price: '$1', stocked: true, name: 'Apple',
    },
    {
      category: 'Fruits', price: '$1', stocked: true, name: 'Dragonfruit',
    },
    {
      category: 'Fruits', price: '$2', stocked: false, name: 'Passionfruit',
    },
    {
      category: 'Vegetables', price: '$2', stocked: true, name: 'Spinach',
    },
    {
      category: 'Vegetables', price: '$4', stocked: false, name: 'Pumpkin',
    },
    {
      category: 'Vegetables', price: '$1', stocked: true, name: 'Peas',
    },
    ];

  res.send({ products });
});
```

`http://localhost:3000/products` 접속하여 확인

CommandLine으로 확인

`curl localhost:3000/products`

`http localhost:3000/products`
