Http Client

2woongjae@gmail.com

Mark Lee (이웅재)

  • Studio XID inc. ProtoPie Engineer
  • Seoul.JS 오거나이저
  • 타입스크립트 한국 유저 그룹 오거나이저
  • 일렉트론 한국 유저 그룹 운영진
  • Seoul.js 오거나이저
  • Microsoft MVP - Visual Studio and Development Technologies
  • Code Busking with Jimmy
    • https://www.youtube.com/channel/UCrKE8ihOKHxYHBzI0Ys-Oow

Http Client ???

브라우저 (Browser)

서버

(Node.js)

서버

 

요청을 받으면

해당 일을 하고

응답을 돌려줌.

request (요청)

response (응답)

request (요청)

response (응답)

시간차

시간차

node.js

browser

axios  35360

2018.02

axios

  • Make XMLHttpRequests from the browser
  • Make http requests from node.js
  • Supports the Promise API
  • Intercept request and response
  • Transform request and response data
  • Cancel requests
  • Automatic transforms for JSON data
  • Client side support for protecting against XSRF

프로젝트 준비

~/Project/workshop-201801 
➜ npx create-react-app react-ts-http --scripts-version=react-scripts-ts

~/Project/workshop-201801 took 1m 47s 
➜ cd react-ts-http/

Project/workshop-201801/react-ts-http is 📦 v0.1.0 via ⬢ v8.9.4 
➜ npm i axios -D
+ axios@0.17.1
added 3 packages in 7.491s

Project/workshop-201801/react-ts-http is 📦 v0.1.0 via ⬢ v8.9.4 
➜ npm i react-router-dom @types/react-router-dom -D
+ react-router-dom@4.2.2
+ @types/react-router-dom@4.2.3
added 10 packages in 9.751s

App.tsx

import * as React from 'react';
import './App.css';
import { BrowserRouter as Router, Route, Switch, Link } from 'react-router-dom';
import AxiosTest from './components/AxiosTest';

const logo = require('./logo.svg');

const Routes = () => (
  <div>
    <ul>
      <li>
        <Link to="/">Axios</Link>
      </li>
    </ul>
  </div>
);

class App extends React.Component {
  render() {
    return (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <h1 className="App-title">Welcome to React</h1>
        </header>
        <Router>
          <div>
            <Routes />
            <Switch>
              <Route path="/" component={AxiosTest} />
            </Switch>
          </div>
        </Router>
      </div>
    );
  }
}

export default App;

Promise AxiosTest.tsx

import * as React from 'react';
import axios from 'axios';

export default class AxiosTest extends React.Component {
  componentDidMount() {
    axios
      .get('https://api.github.com/users')
      .then(response => {
        console.log('========== ========== ==========');
        console.log(response);
        console.log('========== ========== ==========');
      })
      .catch(error => {
        console.log('========== ========== ==========');
        console.log(error);
        console.log('========== ========== ==========');
      });
  }
  render() {
    return (
      <div>
        <h2>Axios Test</h2>
      </div>
    );
  }
}

async-await AxiosTest.tsx

import * as React from 'react';
import axios from 'axios';

export default class AxiosTest extends React.Component {
  async componentDidMount() {
    let response = null;
    try {
      response = await axios.get('https://api.github.com/users');
    } catch (error) {
      console.log('========== ========== ==========');
      console.log(error);
      console.log('========== ========== ==========');
    }
    if (response !== null) {
      console.log('========== ========== ==========');
      console.log(response);
      console.log('========== ========== ==========');
    }
  }
  render() {
    return (
      <div>
        <h2>Axios Test</h2>
      </div>
    );
  }
}

GET https://api.github.com/users

isomorphic-fetch

  • This adds fetch as a global so that its API is consistent between client and server.
  • You must bring your own ES6 Promise compatible polyfill, I suggest es6-promise.

프로젝트 준비

~/Project/workshop-201801 
➜ npx create-react-app react-ts-http --scripts-version=react-scripts-ts

~/Project/workshop-201801 took 1m 47s 
➜ cd react-ts-http/

Project/workshop-201801/react-ts-http is 📦 v0.1.0 via ⬢ v8.9.4 
➜ npm i axios -D
+ axios@0.17.1
added 3 packages in 7.491s

Project/workshop-201801/react-ts-http is 📦 v0.1.0 via ⬢ v8.9.4 
➜ npm i react-router-dom @types/react-router-dom -D
+ react-router-dom@4.2.2
+ @types/react-router-dom@4.2.3
added 10 packages in 9.751s

Project/workshop-201801/react-ts-http is 📦 v0.1.0 via ⬢ v8.9.4 took 10s 
➜ npm i isomorphic-fetch @types/isomorphic-fetch -D
+ isomorphic-fetch@2.2.1
+ @types/isomorphic-fetch@0.0.34
added 1 package and updated 1 package in 8.798s

App.tsx

import * as React from 'react';
import './App.css';
import { BrowserRouter as Router, Route, Switch, Link } from 'react-router-dom';
import AxiosTest from './components/AxiosTest';

const logo = require('./logo.svg');

const Routes = () => (
  <div>
    <ul>
      <li>
        <Link to="/">Axios</Link>
      </li>
    </ul>
  </div>
);

class App extends React.Component {
  render() {
    return (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <h1 className="App-title">Welcome to React</h1>
        </header>
        <Router>
          <div>
            <Routes />
            <Switch>
              <Route path="/" component={AxiosTest} />
            </Switch>
          </div>
        </Router>
      </div>
    );
  }
}

export default App;

Promise IsomorphicFetchTest.tsx

import * as React from 'react';
import * as fetch from 'isomorphic-fetch';

export default class IsomorphicFetchTest extends React.Component {
  componentDidMount() {
    fetch('https://api.github.com/users')
      .then(response => {
        if (response.status >= 400) {
          throw new Error('Bad response from server');
        }
        console.log('========== ========== ==========');
        console.log(response);
        console.log('========== ========== ==========');
      })
      .catch(error => {
        console.log('========== ========== ==========');
        console.log(error);
        console.log('========== ========== ==========');
      });
  }
  render() {
    return (
      <div>
        <h2>IsomorphicFetch Test</h2>
      </div>
    );
  }
}

async-await IsomorphicFetchTest.tsx

import * as React from 'react';
import * as fetch from 'isomorphic-fetch';

export default class IsomorphicFetchTest extends React.Component {
  async componentDidMount() {
    let response = null;
    try {
      response = await fetch('https://api.github.com/users');
    } catch (error) {
      console.log('========== ========== ==========');
      console.log(error);
      console.log('========== ========== ==========');
    }
    if (response !== null) {
      if (response.status >= 400) {
        throw new Error('Bad response from server');
      }
      console.log('========== ========== ==========');
      console.log(response);
      console.log('========== ========== ==========');
    }
  }
  render() {
    return (
      <div>
        <h2>IsomorphicFetch Test</h2>
      </div>
    );
  }
}

GET https://api.github.com/users 400

GET https://api.github.com/users 401

superagent

  • SuperAgent is a small progressive client-side HTTP request library, and Node.js module with the same API, sporting many high-level HTTP client features. View the docs.

프로젝트 준비

~/Project/workshop-201801 
➜ npx create-react-app react-ts-http --scripts-version=react-scripts-ts

~/Project/workshop-201801 took 1m 47s 
➜ cd react-ts-http/

Project/workshop-201801/react-ts-http is 📦 v0.1.0 via ⬢ v8.9.4 
➜ npm i axios -D
+ axios@0.17.1
added 3 packages in 7.491s

Project/workshop-201801/react-ts-http is 📦 v0.1.0 via ⬢ v8.9.4 
➜ npm i react-router-dom @types/react-router-dom -D
+ react-router-dom@4.2.2
+ @types/react-router-dom@4.2.3
added 10 packages in 9.751s

Project/workshop-201801/react-ts-http is 📦 v0.1.0 via ⬢ v8.9.4 took 10s 
➜ npm i isomorphic-fetch @types/isomorphic-fetch -D
+ isomorphic-fetch@2.2.1
+ @types/isomorphic-fetch@0.0.34
added 1 package and updated 1 package in 8.798s

Project/workshop-201801/react-ts-http is 📦 v0.1.0 via ⬢ v8.9.4 took 10s 
➜ npm i superagent @types/superagent -D
+ superagent@3.8.2
+ @types/superagent@3.5.7
added 6 packages in 9.734s

App.tsx

import * as React from 'react';
import './App.css';
import { BrowserRouter as Router, Route, Switch, Link } from 'react-router-dom';
import AxiosTest from './components/AxiosTest';
import IsomorphicFetchTest from './components/IsomorphicFetchTest';
import SuperagentTest from './components/SuperagentTest';

const logo = require('./logo.svg');

const Routes = () => (
  <div>
    <ul>
      <li>
        <Link to="/">Axios</Link>
      </li>
      <li>
        <Link to="/isomorphic-fetch">Isomorphic Fetch</Link>
      </li>
      <li>
        <Link to="/superagent">Superagent</Link>
      </li>
    </ul>
  </div>
);

class App extends React.Component {
  render() {
    return (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <h1 className="App-title">Welcome to React</h1>
        </header>
        <Router>
          <div>
            <Routes />
            <Switch>
              <Route exact={true} path="/" component={AxiosTest} />
              <Route path="/isomorphic-fetch" component={IsomorphicFetchTest} />
              <Route path="/superagent" component={SuperagentTest} />
            </Switch>
          </div>
        </Router>
      </div>
    );
  }
}

export default App;

Promise SuperagentTest.tsx

import * as React from 'react';
import * as request from 'superagent';

export default class SuperagentTest extends React.Component {
  componentDidMount() {
    request.get('https://api.github.com/users').end((error, response) => {
      if (error) {
        console.log('========== ========== ==========');
        console.log(error);
        console.log('========== ========== ==========');
        return;
      }
      console.log('========== ========== ==========');
      console.log(response);
      console.log('========== ========== ==========');
    });
  }
  render() {
    return (
      <div>
        <h2>Superagent Test</h2>
      </div>
    );
  }
}

async-await SuperagentTest.tsx

import * as React from 'react';
import * as request from 'superagent';

export default class SuperagentTest extends React.Component {
  async componentDidMount() {
    let response = null;
    try {
      response = await request.get('https://api.github.com/user');
    } catch (error) {
      console.log('========== ========== ==========');
      console.log(error);
      console.log('========== ========== ==========');
    }
    if (response !== null) {
      console.log('========== ========== ==========');
      console.log(response);
      console.log('========== ========== ==========');
    }
  }
  render() {
    return (
      <div>
        <h2>Superagent Test</h2>
      </div>
    );
  }
}

GET https://api.github.com/users 400

GET https://api.github.com/users 401

[CODEBUSKING WORKSHOP] Http Client

By Woongjae Lee

[CODEBUSKING WORKSHOP] Http Client

코드버스킹 워크샵 - React with TypeScript 세번째 (2018년 1월 버전)

  • 1,291