1. Http call

1.1. Http call approaches

  • Node
    • http
    • request (✅)
  • Browser
    • XMLHttpRequest
    • jQuery
    • Framework-based (Angular http service)
    • Fetch (✅ polyfill for both regular version or isomorphic-fetch)
  • Node & Browser (any below is good)
    • isomorphic-fetch
    • xhr
    • superAgent
    • axios (great)

1.1.1. Fetch

You can find compatibility for fetch: https://caniuse.com/#search=fetch

Fetch cannot be cancelled at this time.

const request = new Request('http://your-api.com/user', {
  method: 'GET',
  mode: 'cors',
  headers: new Headers({
    'Content-Type': 'text/html; charset=UTF-8',
  }),
});
fetch(request).then(onSuccess, onError);

1.1.2. Axios

axios({
  url: 'http://your-api.com/user',
  method: 'post',
  headers: {
    'Content-type': 'text/html; charset=UTF-8',
  },
  data: 'text',
}).then(onSuccess, onError);

1.2. Why centralize API calls

  • Configure all calls
  • Handle preloader logic
  • Handle errors
  • Single seam(缝合;接合) for mocking

create src/api/userApi.js

import 'whatwg-fetch'; // let browser that hasn't supported fetch work with fetch

const onSuccess = (response) => response.json();
const onError = (error) => console.log(error); //eslint-disable-line no-console
const get = (url) => fetch(url).then(onSuccess, onError);

export const getUsers = () => get('users');

So in index.js, I can call this api:

import { getUsers } from './api/userApi';
getUsers().then((result) => {});

Only send polyfill to those who need it: <script src="https://cdn.polyfill.io/v2/polyfill.js?features=fetch"></script>

1.3. Mock

1.3.1. Why Mock HTTP?

  • Unit Testing
  • Instant response
  • Keep working when services are down
  • Rapid prototyping
  • Avoid inter-team bottlenecks
  • Work offline

1.3.2. How to Mock HTTP (also review interview/frontend/Mock.md)

  • Nock (mock http calls in unit test)
  • Static JSON
  • Create development webserver
    • api-mock
    • JSON server
    • JSON Schema faker(random data)
    • Browsersync
    • Express, etc.

My json server: https://my-json-server.typicode.com/

1.3.3. Authentication

1.3.4. Our Plan for Mocking HTTP

  1. Declare our schema:
    • JSON Schema Faker
  2. Generate Random Data:
    • faker.js
    • chance.js
    • randexp.js
  3. Serve Data via API
    • JSON Server

1.3.5. Mocking Libraries

Json Schema Json Schema Faker

1.3.6. Demo

1. create Schema: buildScripts/mockDataSchema.js

export const schema = {
  type: 'object',
  properties: {
    users: {
      type: 'array',
      minItems: 3,
      maxItems: 5,
      items: {
        type: 'object',
        properties: {
          id: {
            type: 'number',
            unique: true,
            minimum: 1,
          },
          firstName: {
            type: 'string',
            faker: 'name.firstName',
          },
          lastName: {
            type: 'string',
            faker: 'name.lastName',
          },
          email: {
            type: 'string',
            faker: 'internet.email',
          },
        },
        required: ['id', 'firstName', 'lastName', 'email'],
      },
    },
  },
  required: ['users'],
};

2. generate Mock Data: buildScripts/generateMockData.js

import jsf from 'json-schema-faker';
import { schema } from './mockDataSchema';
import fs from 'fs';
import chalk from 'chalk';

const json = JSON.stringify(jsf(schema));

fs.writeFile('./src/api/db.json', json, (err) => {
  if (err) {
    return console.log(chalk.red(err));
  } else {
    console.log(chalk.green('Mock data generated.'));
  }
});

npm scripts:

"generate-mock-data": "babel-node buildScripts/generateMockData"

Run npm run generate-mock-data and you should see src/api/db.json.

3. serving mock data via json server

npm scripts:

"start-mockapi": "json-server --watch src/api/db.json --port 3001"

npm run start-mockapi and access http://localhost:3001/users, you should see the data

I prefer to change data every time when restarting the app.

Randomized data is helpful.

  • empty lists
  • long lists
  • long value
  • testing
  • filtering
  • sorting

To change data, follow below:

npm scripts:

"start": "npm-run-all --parallel security-check start:server lint:watch test:watch start-mockapi",
"generate-mock-data": "babel-node buildScripts/generateMockData",
"prestart-mockapi": "npm run generate-mock-data",
"start-mockapi": "json-server --watch src/api/db.json --port 3001"

Targeting mock api or production api by environment

Assume srcServer.js's app.get('/users') is called only for production, while in dev mode, we should hit Json-server port 3001. So when requesting localhost:3000/, we know it's development environment and call getUsers api which hosting in port 3001 by Json-server. When request http://production, we call production api.

api/baseUrl.js

export default function getBaseUrl() {
  const inDevelopment = window.location.hostname === 'localhost';
  return inDevelopment ? 'http://localhost:3001/' : '/'; // first is json-server address, second is production api address
}

api/userApi.js

import getBaseUrl from './baseUrl';
const baseUrl = getBaseUrl();
const get = (url) => fetch(baseUrl + url).then(onSuccess, onError);

delete user for Json-server

index.js

const deleteLinks = document.querySelectorAll('.deleteUser');
Array.from(deleteLinks, (link) => {
  link.onclick = (e) => {
    const ele = e.target;
    e.preventDefault();
    deleteUser(ele.dataset.id);
    const row = ele.parentNode.parentNode; // tr
    row.parentNode.removeChild(row);
  };
});

userApi.js

const del = (url) => {
  const request = new Request(baseUrl + url, {
    method: 'delete',
  });
  return fetch(request).then(onSuccess, onError);
};
export const deleteUser = (id) => del(`users/${id}`);
Copyright © Guanghui Wang all right reserved,powered by GitbookFile Modified: 2019-08-25 13:56:34

results matching ""

    No results matching ""