前端共享让前端飞React Native开发

使用react native 创建一个属于你自己的云备忘录app

2018-03-05  本文已影响142人  mytac

前言

写这个的初衷是由于现在的记事本app都太冗余了,我很喜欢google的keep,但要是想同步的话还要翻墙;有道云笔记又有些大,ui也不够直观,太办公向了,写博客我很喜欢,但随手写点备忘录,还是显得有点重。正好我使用react native也有一段时间了,学node一直也找不到自己喜欢的项目练手,不如就自己写一个吧~

在写这个项目之前,可以说一点都不了解mongoDB,不了解他的数据结构;可以说是一个完全的后端小白了。。

如果对这个项目有兴趣的朋友可以在github上点下star,本人也会一直更新迭代~有疑问和建议的朋友可以在评论区指出 ~嘻嘻

起步

先建个服务

// server.js
const express=require('express')
const app=express()

// 用于上传笔记
app.get('/upload',(req,res)=>{
    res.send('uploaded!!')
})

const server=app.listen(8888,()=>{
    const host=server.address().address
    const port=server.address().port

    console.log(`the server is listening on ${host}:${port}`)
})

初始化路由

基本上有三个路由,上传,删除,查找

// server.js

// 上传文章
app.get('/upload', (req, res) => {
  res.send('uploaded!!');
});

// 删除文章
app.get('/delete', (req, res) => {
  res.send('delete!!');
});

// 按分类查找
app.get('/findByLabel', (req, res) => {
  res.send('findByLabel!!');
});

初始化数据库

数据库使用mongodb,我用的是node-mongodb-native作为引擎他是mongodb官方的node引擎,express官网上推荐的mongoskin,有一年多没更新了就放弃了。

新建一个数据库配置文件,

const { MongoClient } = require('mongodb');
const assert = require('assert');

// Connection URL
const url = 'mongodb://localhost:27017';

// Database Name
const dbName = 'memo';

function connectDB() {
  // Use connect method to connect to the server
  MongoClient.connect(url, (err, client) => {
    assert.equal(null, err);
    console.log('Connected successfully to server');

    const db = client.db(dbName);

    client.close();
  });
}

module.exports = { connectDB };

在server.js中引用这个模块,启动服务后,终端打印了Connected successfully to server,即为连接成功。

自定义配置

将配置信息单独放在一个文件夹中,方便维护。这里写入了监听端口和数据库信息,如果有其他的,将在后面加入。

module.exports = {
  port: 8888,
  mongodb: 'mongodb://localhost:27017',
  dbName: 'memo',
};

使用promise重构连接数据库方法

查看了文档,因为其他操作数据库的api都依赖于MongoClient.connect方法中的回调函数中的参数client。因为操作数据库复杂,为了使代码更清晰,同时避免回调地狱,使用promise做个封装,进行链式调用。

// mongo.js
const connectDB = new Promise((resolve, reject) => {
  MongoClient.connect(mongodbURL, (err, client) => {
    if (err) {
      reject(err);
    } else {
      assert.equal(null, err);
      console.log('Connected successfully to server');

      const db = client.db(dbName);
      resolve(db);
    }
  });
});

module.exports = { connectDB };

调用:

connectDB.then((db) => {
  findDocuments(db);
});

编写添加方法

基础模板

const assert = require('assert');

const insertDocuments = function (db, callback = () => {}) {
  // Get the documents collection
  const collection = db.collection('documents');
  // Insert some documents
  collection.insertOne({ a: 'test' }, (err, result) => {
    assert.equal(err, null);
    assert.equal(1, result.result.n);
    assert.equal(1, result.ops.length);
    console.log('Inserted a document into the collection');
    callback(result);
  });
};

module.exports = { insertDocuments };

其他的操作,如删除或查找,都可以在官方文档上都可以找到,就不一一举例了。

创建错误实例

包括一个请求状态码和错误码

// createError.js
function createError(code = 1) {
  return {
    status: 1,// 1为错误;0为成功
    code,
  };
}

module.exports = { createError };

我们再编写几个可能会出现的错误实例,如:

// error.js
const errors = {
  CONNECT_DB_FAILED: 'CONNECT_DB_FAILED', // 连接数据库失败

};

稍微更改下connectDB的逻辑:

const connectDB = new Promise((resolve, reject) => {
  MongoClient.connect(mongodbURL, (err, client) => {
    if (err) {
      reject(createError(errors.CONNECT_DB_FAILED));
    } else {
      const db = client.db(dbName);
      resolve(db);
    }
  });
});

尝试把config.js中的mongodbURL更改为错误的地址,查看终端是否打印{ status: 1, code: 'CONNECT_DB_FAILED' }

用promise封装添加方法

由于官方给出的代码例子都是回调形式,代码意图不清晰,使用promise封装,避免回调地狱。

const insertDocuments = (db, data = { test: 1 }, collectionName = 'documents') => new Promise((resolve, reject) => {
  const collection = db.collection(collectionName);
  collection.insertOne(data, (err, { result }) => {
    if (err) {
      reject(createError(errors.HANDLE_DB_FAILED));
    } else {
      resolve(createResult(result));
    }
  });
});

在index.js中,更改调用方式,终端会打印data { status: 0, body: { n: 1, ok: 1 } }

connectDB
  .then(db => insertDocuments(db))
  .then(data => console.log('data', data))
  .catch((err) => {
    console.log(err);
  });

解析请求

我们发送的请求中的数据,要放到req.body中去接收,这里需要安装express的中间件bodyParser

const bodyParser = require('body-parser');
app.use(bodyParser.json({ extended: true }));

使用postman测试一下,发送请求{{URL}}/upload,body中写入

{
    "context":"hello world"
}

我们编写一下upload函数,来打印一下

function upload(req, res) {
  const { context } = req.body;
  console.log(context) // hello world
  res.send('uploaded!!');
}

控制台有输出,则成功。

之后,把之前写好的上传函数写入upload中。

function upload(req, res) {
  const { context } = req.body;
  connectDB
    .then(db => insertDocuments(db, context))
    .then(data => console.log('data', data))
    .catch((err) => {
      console.log(err);
    });
  res.send('uploaded!!');
}

执行正常,则会返回{ status: 0, body: { n: 1, ok: 1 } }

错误实例分类

在请求的过程中,可能会发生网络错误、数据库错误或是接口参数错误;如果单纯的返回一个错误状态,整个服务就显得太不可靠了。

在constants文件夹下创建一个错误常量的对象,在后续的开发过程中我们将加入更多的错误类型,先简单写这几个

const errors = {
  CONNECT_DB_FAILED: 'CONNECT_DB_FAILED', // 连接数据库失败
  HANDLE_DB_FAILED: 'HANDLE_DB_FAILED', // 与数据库操作时发生错误
  INVALID_PARAMETERS: 'INVALID_PARAMETERS', // 参数错误
  SYSTEM_ERROR: 'SYSTEM_ERROR', // 系统错误,可能是语法,查看日志

};

module.exports = errors;

然后,我们再创建几个错误处理函数,用于把错误类型传递到响应参数中。如下:

function parameterInvalid(res) {
  res.json(createError(INVALID_PARAMETERS));
}

function unknowError(err, res) {
  console.log(err);
  res.json(createError(SYSTEM_ERROR));
}

module.exports = { parameterInvalid, unknowError };

把上面的函数写进upload方法中:

const { parameterInvalid, unknowError } = require('../lib/handleErrors');

function upload(req, res) {
  const { context } = req.body;
  if (!context) {
    parameterInvalid(res);
    return;
  }

  connectDB
    .then(db => insertDocuments(db, { context }))
    .then(data => res.json(data))
    .catch((err) => { unknowError(err, res); });
}

以上,一个基础的上传服务就完成了~~ 还有其他的操作,如删除、更新等,其实都大同小异,区别于node-mongo的api,大家可以查阅官方文档或是查看项目源代码~

上一篇 下一篇

猜你喜欢

热点阅读