基于阿里的Node全栈之路(五)前后端分离进阶-接口篇

简介: 上一篇文章我就简单的贴了下代码,放出来不到一天就破千了,这让我非常的意外,也很开心;) 我会好好的把上一篇的代码注释补一下的。然后决定再放一些我的代码和理解,俗话说: Talk is cheap, show me the code! 花了一个中午写的,希望大家能喜欢,也欢迎交流!

上一篇文章我就简单的贴了下代码,放出来不到一天就破千了,这让我非常的意外,也很开心;) 我会好好的把上一篇的代码注释补一下的。然后决定再放一些我的代码和理解,俗话说:

Talk is cheap, show me the code!

还记得我的架构中,只有前端静态代码,同时所有的请求是经过跨域发到api上的,那么这次,我们就来好好的分析下request接口的实现和我自己尝试的一种的开发流程——api文档(新接口文档)


_1_

先贴上我之前的前后端分离的方式,再简单的介绍下,看过前面文章的同学直接跳过哈!
看这个图,我现在对web端的开发,因为是用vue写的,vue本身会把代码打包成静态文件:

  • -static
  • -index.html

这样意味着,用了vue或者类似框架的时候,我们会抛弃了以前的一个东西叫动态web语言,具体点就是说像asp、jsp等,在客户访问前会根据一些条件渲染出对应的网页出来,而这正是vue这类型的框架要实现的功能,嗯,可以说是冲突了。我当时还会习惯性的部署docker容器来存放这些静态资源,然后启动一个node express来监听接口,但后来仔细想想,这不是像OSS这些要做的事情吗!? 所以,就有了前面的两篇文章:

  1. [基于阿里的Node全栈之路(三)利用阿里云OSS实现前后端分离
    编辑 删除](https://yq.aliyun.com/articles/216361)
  2. 基于阿里的Node全栈之路(四)前后端分离进阶-自动上传前端代码到OSS

嗯嗯,这也是我前后端分离的第一步。

好,上面都是重新温故下我之前的文章,因为我发现看我前面几篇文章好像并没有想象中的那么容易阅读,所以再次重温一遍。

敲黑板!敲黑板!

这次,我分享的是我对api请求接口的封装,可能很多同学会说,这有什么难的,要用请求的时候,调用一下ajax什么的就可以了。emmm..., 是可以的,不过那样的代码对于非常追求代码美感的我来说,是灰常难忍受的!

既然我们是前后端分离,那么我们应该规对接的接口的结构,对吧?我在项目中,强制规定所有的api都应该长这样

const api_host = `https://api.${你的域名}\${你的项目名\${api_version}`;//https://api.xxxxx.com/blog/v1
//api遵循restful设计,这里规定api返回结构
const response = {
  code:Number,
  /*
   * 小于0是错误,这里前端不需要关心错误是什么,
   * 等于0是没有权限
   * 大于0表示成功
   * 我这么设计是由原因的,欢迎大家来一起探讨
   */
  msg:String,//当然,你也可以叫errMsg,message什么的,随便你啦
  /*
   * 在我这里,默认只有错误的时候,才会出现
   */
  data:Object,
  /* 
   * 后端返回对象,我们一直说前后端语言一样,有很多好处,呐,这里就是!
   * 这样写,基本能保证后端传给前端是什么,前端收到的就是什么
   */
};

下面放上我的代码,然后我再详细解析下:

/* eslint-disable */
import axios from 'axios';

const MyPlugin = {};
axios.defaults.withCredentials = true;//唯有加上这句话,才能够支持跨域请求,如果实在不明白的可以留言

MyPlugin.install = function install(Vue, api_host) {
  //构建axios请求基础
  const request = axios.create({
    baseURL: api_host,//api host:顾名思义就是api的请求基础地质
    timeout: 30000// 超时时间
  });
  //请求方法的构建,type为:get、post、delete等等
  const createRequestFuc = (type) => {
    return function (resource, params, showError = true) {
      //返回请求的Promise的对象
      return new Promise((resolve, reject) => {
        this.$Loading.start();//请求发起时,show loading,一般的框架都会有全局调用的loading方法。
        params = type === 'get' ? { params } : params;//axios里get方法和其它方法接收参数的方式不一致,这里做个统一
        request[type](resource, params)//调用request
          .then(res => {
            if (res && res.data && res.data.code > 0) {//判断请求返回结果,code为判断值,这里可以替换成你自己的框架定义
              resolve(res.data.data);//返回结果
            } else {
              showError && this.$Message.error(res.data.msg);//判断是否调用自带全局waring或error
              reject(res.data.msg);//无论上面是否执行,都应该reject,阻止代码继续执行
            }
            this.$Loading.finish();//结束loading
          })
          .catch((err) => {
            this.$Message.error('请求失败!');//这种情况一般是请求失败,报错方式可以自己更改
            this.$Loading.finish();//结束loading
            reject(err);//无论上面是否执行,都应该reject,阻止代码继续执行
          });
          //特别注意:vue install方式安装的插件,this就是vue component对象。
      });
    }
  }
  //构建请求
  Vue.prototype.$get = createRequestFuc('get');
  Vue.prototype.$put = createRequestFuc('put');
  Vue.prototype.$post = createRequestFuc('post');
  Vue.prototype.$patch = createRequestFuc('patch');
  Vue.prototype.$delete = createRequestFuc('delete');
};
export default MyPlugin;
/* eslint-enable */

这是一个我写的插件,上篇文章讲到vue项目用webpack模板构建对吧,那么你现在写前端项目应该都是以".vue"结尾的文件,那么你只需要在main.js里面把它引用进来就可以了:

import Vue from 'vue';
import Request from '@/plugins/request';


Vue.use(Vuex);
Vue.use(Request,'https://api.xxxxx.com/v1');//这里

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  store,
  template: '<App/>',
  components: { App },
});
/* eslint-enable no-new */

好,到这里估计写过vue的老鸟都已经明白了,没搞懂的童鞋嘞,那就继续看下去吧!
接下来,你只需要在vue文件里面直接使用就行了,这里再贴一份简单登录代码给大家参考:

<template>
  <div class="login">
    <Input type="text" v-model="user_form.username" placeholder="phone">
    <Input type="password" v-model="user_form.password" placeholder="phone">
    <Button type="primary" @click="login">Log in</Button>
  </div>
</template>
<script>

export default {
  async created() {
    const session = await this.$get('session', {}, false);
    this.setSession(session);
  },
  data() {
    return {
      user_form: {
        phone: '',
        password: '',
      },
    };
  },
  methods: {
    async login() {
      const session = await this.$post('session', this.user_form);
      this.setSession(session);
    },
    setSession(session) {
      //这里放置像vuex这些,存放session的fangfa,当然!你也可以用vuex的mapMutations,我就是这么做的^.^
    },
  },
};
</script>

嘿嘿,上面的代码简单不。当然,你要喜欢promise回调或者yield都一样的,随便你,我这里只是想分享一种思想,因为这种方式,是可以在node里面得到广泛应用的,为了证明这点,我再贴一份我的react-native版本的request接口:

/* eslint-disable */
import axios from 'axios';
import { ShowWarnMsg } from './toast';
const api_host = 'https://api.xxxxxx.com/project_name/v1';

//构建axios请求基础
const request = axios.create({
  baseURL: api_host,//api host:顾名思义就是api的请求基础地质
  timeout: 30000// 超时时间
});
//请求方法的构建,type为:get、post、delete等等
const createRequestFuc = (type) => {
  return function (resource, params, showError = true) {
    //返回请求的Promise的对象
    return new Promise((resolve, reject) => {
      params = type === 'get' ? { params } : params;//axios里get方法和其它方法接收参数的方式不一致,这里做个统一
      request[type](resource, params)//调用request
        .then(res => {
          if (res && res.data && res.data.code > 0) {//判断请求返回结果,code为判断值,这里可以替换成你自己的框架定义
            resolve(res.data.data);//返回结果
          } else {
            showError && ShowWarnMsg(res.data.msg);//判断是否调用自带全局waring或error
            reject(res.data.msg);//无论上面是否执行,都应该reject,阻止代码继续执行
          }
        })
        .catch((err) => {
          ShowWarnMsg('请求失败!');//这种情况一般是请求失败,报错方式可以自己更改
          reject(err);//无论上面是否执行,都应该reject,阻止代码继续执行
        });
      //特别注意:vue install方式安装的插件,this就是vue component对象。
    });
  }
};
export const $get = createRequestFuc('get');
export const $put = createRequestFuc('put');
export const $post = createRequestFuc('post');
export const $patch = createRequestFuc('patch');
export const $delete = createRequestFuc('delete');

global.HTTP = {
  $get,
  $put,
  $post,
  $patch,
  $delete,
};

export default global.HTTP;
/* eslint-enable */

区别不大吧,别学我用global,我只是偷懒。

相关文章
|
17天前
|
SQL JavaScript 关系型数据库
node博客小项目:接口开发、连接mysql数据库
【10月更文挑战第14天】node博客小项目:接口开发、连接mysql数据库
|
1月前
|
消息中间件 JavaScript 前端开发
用于全栈数据流的 JavaScript、Node.js 和 Apache Kafka
用于全栈数据流的 JavaScript、Node.js 和 Apache Kafka
40 1
|
22天前
|
前端开发 JavaScript 程序员
【从前端入门到全栈】Node.js 之核心概念
【从前端入门到全栈】Node.js 之核心概念
|
2月前
|
前端开发 JavaScript 安全
node登陆接口权限配置cookie-parser、express-session
本文介绍了在Node.js中使用express-session和cookie-parser实现登录接口的权限配置,包括验证码接口的生成和自定义中间件的创建,用于验证用户权限。
24 0
node登陆接口权限配置cookie-parser、express-session
|
2月前
|
JavaScript 前端开发
vue配合axios连接express搭建的node服务器接口_简单案例
文章介绍了如何使用Express框架搭建一个简单的Node服务器,并使用Vue结合Axios进行前端开发和接口调用,同时讨论了开发过程中遇到的跨域问题及其解决方案。
49 0
vue配合axios连接express搭建的node服务器接口_简单案例
|
3月前
|
开发者 Java 存储
JSF 与 CDI 携手共进,紧跟技术热点,激发开发者情感共鸣,开启高效开发新征程
【8月更文挑战第31天】JavaServer Faces (JSF) 与 Contexts and Dependency Injection (CDI) 在 Java EE 领域中紧密协作,助力开发者高效构建现代 Web 应用。JSF 凭借其丰富的组件库和页面导航功能受到青睐,而 CDI 则优雅地管理对象生命周期并实现依赖注入。两者结合,不仅简化了复杂企业应用的开发,还实现了松耦合架构,增强了代码的灵活性、可维护性和可扩展性。通过示例展示了如何利用 CDI 将业务服务对象注入 JSF Managed Bean,以及如何在不同页面间共享数据,突显了这一组合的强大功能。
39 0
|
3月前
|
JavaScript 前端开发 API
全栈开发革命来临!Vue.js与Node.js联手,打造前后端无缝对接的奇迹之作!
【8月更文挑战第30天】在Web开发领域,前后端分离与协作至关重要。Vue.js以其轻量级和易用性深受前端开发者喜爱,而Node.js则以高性能和事件驱动特性在后端领域崭露头角。二者结合开启了全栈开发新篇章,通过RESTful API或GraphQL实现高效稳定通信。本文以示例说明如何使用Vue.js和Node.js构建全栈应用,从前端Vue组件到后端Express服务器,展示了数据获取与展示的全过程。这种组合提供了一种高效简洁的全栈开发方案,使开发者能更专注于业务逻辑实现。
206 0
|
4月前
|
JavaScript 前端开发 NoSQL
前端node如何学习进阶知识
【7月更文挑战第8天】 深化JavaScript基础,精通Node.js核心模块(如fs、http)与事件循环机制,学习Express框架及异步编程(回调、Promise、async/await),掌握数据库交互,参与实战项目,关注Node.js最新技术和最佳实践,以此提升进阶技能。
44 8
|
4月前
|
前端开发 JavaScript
【node写接口】 通过node 快速搭建一个服务器、get请求、post请求 小白入门
【node写接口】 通过node 快速搭建一个服务器、get请求、post请求 小白入门
95 4
|
5月前
|
SQL JavaScript 前端开发
简单用Nodejs + express 编写接口
【6月更文挑战第3天】该文介绍了如何在Node.js和Express中创建GET和POST接口。首先,简要提到了准备工作,建议查阅上一篇文章。接着展示了GET接口的示例,说明可以直接在浏览器中请求。然后,详细解释了POST接口的步骤,包括引入Express模块、设置路由处理程序、解析请求体及处理请求。最后,强调了编写接口时应注意错误处理、安全性、中间件使用、路由组织、日志记录、性能优化和测试等关键点。作者以肥晨的身份结尾,鼓励关注其分享的前端学习资料和技术动态。
193 1