使用模拟数据的JavaScript虚假API

195 阅读4分钟

在本教程中,我们将实现一个JavaScript假的API。通常情况下,当还没有后台,而你需要针对某种现实的数据来实现你的前端时,这就很有帮助。假冒它,直到你成功!

JavaScript假的API

让我们开始吧。首先,我们需要一些数据,这些数据通常来自我们后台的数据库,但在我们的案例中,这些数据只是来自一个JavaScript文件。

// pseudo database
let users = {
  1: {
    id: '1',
    firstName: 'Robin',
    lastName: 'Wieruch',
    isDeveloper: true,
  },
  2: {
    id: '2',
    firstName: 'Dave',
    lastName: 'Davddis',
    isDeveloper: false,
  },
};

接下来我们需要唯一的标识符,在假数据库中只有两个项目时,这些标识符并不重要,但对于最终创建更多的项目是很重要的。

import { v4 as uuidv4 } from 'uuid';

const idOne = uuidv4();
const idTwo = uuidv4();

let users = {
  [idOne]: {
    id: idOne,
    firstName: 'Robin',
    lastName: 'Wieruch',
    isDeveloper: true,
  },
  [idTwo]: {
    id: idTwo,
    firstName: 'Dave',
    lastName: 'Davddis',
    isDeveloper: false,
  },
};

你可以从这里npm install uuid 安装这个库。我们的假数据库现在已经完成了。

现在我们将继续进行我们的虚假API。因此,我们将遵循CRUD模式,通过假的API从我们的假数据库中创建、读取、更新和删除实体。首先,我们需要用一个假的API请求从数据库中检索所有的项目。

const getUsers = () =>
  Object.values(users);

// usage
const result = getUsers();
console.log(result);

这个函数将我们的项目对象作为一个转换后的数组返回。然而,这只是一个同步返回数据的函数。为了伪造一个API,它需要是异步的。因此,我们将把它包装成一个JavaScript承诺。

const getUsers = () =>
  Promise.resolve(Object.values(users));

// usage (1)
getUsers()
  .then(result => {
    console.log(result);
  });

// usage (2)
const doGetUsers = async () => {
  const result = await getUsers();
  console.log(result);
};

doGetUsers();

我们将使用较长的版本,而不是使用之前的速记承诺版本。

const getUsers = () =>
  new Promise((resolve) => {
    resolve(Object.values(users));
  });

较长的承诺版本使我们也能处理错误。

const getUsers = () =>
  new Promise((resolve, reject) => {
    if (!users) {
      reject(new Error('Users not found'));
    }

    resolve(Object.values(users));
  });

// usage (1)
getUsers()
  .then((result) => {
    console.log(result);
  })
  .catch((error) => {
    console.log(error);
  });

// usage (2)
const doGetUsers = async () => {
  try {
    const result = await getUsers();
    console.log(result);
  } catch (error) {
    console.log(error);
  }
};

doGetUsers();

最后但并非最不重要的是,我们要引入一个假的延迟,以使我们的假API现实化。

const getUsers = () =>
  new Promise((resolve, reject) => {
    if (!users) {
      return setTimeout(
        () => reject(new Error('Users not found')),
        250
      );
    }

    setTimeout(() => resolve(Object.values(users)), 250);
  });

这就是了。调用这个函数感觉就像一个真正的API请求,因为它是异步的(JavaScript promise)并且有一个延迟(JavaScript的setTimeout )。在我们一步步走完这第一个API之后,我们现在将继续进行其他的CRUD操作。

JavaScript假的REST API

传统的REST API可以被看作是与CRUD操作非常相似的。这就是为什么我们要以REST的方式来实现下面的API,为读取项目、创建项目、更新项目和删除项目提供API端点。之前我们已经实现了读取多个项目。

const getUsers = () =>
  new Promise((resolve, reject) => {
    if (!users) {
      return setTimeout(
        () => reject(new Error('Users not found')),
        250
      );
    }

    setTimeout(() => resolve(Object.values(users)), 250);
  });

接下来,我们将实现读取单个项目的等效功能;这与其他API没有什么不同。

const getUser = (id) =>
  new Promise((resolve, reject) => {
    const user = users[id];

    if (!user) {
      return setTimeout(
        () => reject(new Error('User not found')),
        250
      );
    }

    setTimeout(() => resolve(users[id]), 250);
  });

// usage
const doGetUsers = async (id) => {
  try {
    const result = await getUser(id);
    console.log(result);
  } catch (error) {
    console.log(error);
  }
};

doGetUsers('1');

接下来,创建一个项目。如果没有提供新项目的所有信息,API将抛出一个错误。否则就会为该项目生成一个新的标识符,并用于在伪数据库中存储该新项目。

const createUser = (data) =>
  new Promise((resolve, reject) => {
    if (!data.firstName || !data.lastName) {
      reject(new Error('Not all information provided'));
    }

    const id = uuidv4();
    const newUser = { id, ...data };

    users = { ...users, [id]: newUser };

    setTimeout(() => resolve(true), 250);
  });

// usage
const doCreateUser = async (data) => {
  try {
    const result = await createUser(data);
    console.log(result);
  } catch (error) {
    console.log(error);
  }
};

doCreateUser({ firstName: 'Liam', lastName: 'Wieruch' });

接下来,更新一个项目。如果没有找到该项目,API将抛出一个错误。否则,item对象中的项目将被更新。

const updateUser = (id, data) =>
  new Promise((resolve, reject) => {
    if (!users[id]) {
      return setTimeout(
        () => reject(new Error('User not found')),
        250
      );
    }

    users[id] = { ...users[id], ...data };

    return setTimeout(() => resolve(true), 250);
  });

// usage
const doUpdateUser = async (id, data) => {
  try {
    const result = await updateUser(id, data);
    console.log(result);
  } catch (error) {
    console.log(error);
  }
};

doUpdateUser('1', { isDeveloper: false });

最后但并非最不重要的是,删除一个项目。和之前一样,如果找不到这个项目,API会返回一个错误。否则,我们只得到确认,该项目已经从物品对象中删除。

const deleteUser = (id) =>
  new Promise((resolve, reject) => {
    const { [id]: user, ...rest } = users;

    if (!user) {
      return setTimeout(
        () => reject(new Error('User not found')),
        250
      );
    }

    users = { ...rest };

    return setTimeout(() => resolve(true), 250);
  });

// usage
const doDeleteUser = async (id) => {
  try {
    const result = await deleteUser(id);
    console.log(result);
  } catch (error) {
    console.log(error);
  }
};

doDeleteUser('1');

我们已经为一个RESTful资源(这里是用户资源)实现了整个假的API。它包括所有的CRUD操作,有一个假的延迟并返回一个异步的结果。对于写操作,API只返回一个确认(布尔值),然而,你也可以决定返回一个标识符(例如,被删除的项目的标识符)或一个项目(例如,创建/更新的项目)。