结对项目分析总结

结对项目分析总结

综述

说实话这次的项目对我的提升并不大,无论是前端、后端我过去都有所经验,对于团队协作、版本控制、自动化CI/CD也有所了解。所以本篇博客我不会将主要的分析放在前后端的实现上,更多的着眼于部署等方面。

附项目体验地址

前后端实现

我们完成的是典型的前后端分离项目,首先要做的就是落实前后端交互格式,我们采用了JSON这种轻量的数据交换格式,具体格式约定如下:

{
  "status": "success",
  "data": interface{}
}
{
  "status": "error",
  "err_msg": "error message"
}

接下来我们要做的就是前后端的分别实现,前端的实现我们放到代码复用部分讲,这里我们看看后端。后端我们选择Python作为主要的开发工具,我们先来看APP的实例获取过程:

from flask import Flask
from flask_cors import CORS
from app.config import FlaskConfig
from app.controllers import register_routers
from app.models import connect_db


def new_flask_app() -> Flask:
    app = Flask(__name__)
    CORS(app, supports_credentials=True)

    # 添加配置文件
    app.config.from_object(FlaskConfig)

    # 注册路由
    register_routers(app)

    # 链接数据库
    connect_db(app)

    return app

代码中的注释都比较详细,不想讲很多。大家注意一下Python中的类型注解这一个特性这样可以获得非常好的代码提示等IDE支持。

接下来,我们分别看一个Model和Controller的例子:

from app.models import db
from app.models import session_commit


class User(db.Model):
    id = db.Column(db.Integer, autoincrement=True, primary_key=True)
    username = db.Column(db.String, nullable=True)
    password = db.Column(db.String, nullable=True)

    def __init__(self, username, password):
        self.username = username
        self.password = password

    def __str__(self):
        return "User(username={})".format(self.username)

    @classmethod
    def check_password(cls, username: str):
        return cls.query.filter_by(username=username).first()

    @classmethod
    def change_password(cls, username: str, password: str):
        user = cls.query.filter_by(username=username).first()
        user.password = password
        return session_commit()

    def new_user(self):
        db.session.add(self)
        return session_commit()

注意其中类方法的使用即可,其余的就是简单的Python的ORM的使用

  
from flask import Blueprint, request, session
from app.models.user import User
import app.utils.return_warp as warp

login_out_page = Blueprint('login_out', __name__, url_prefix='/log')


@login_out_page.route('/in', methods=['POST'])
def login():
    username = request.form.get('username')
    password = request.form.get('password')
    # 校验必须参数
    if username is None or password is None:
        return warp.fail_warp('params error')

    user = User.check_password(username=username)

    if user.password == password:
        session.clear()
        session['user'] = username
        return warp.success_warp('login success')
    else:
        return warp.fail_warp('user error')


@login_out_page.route('/out', methods=['GET'])
def logout():
    session.clear()

    return warp.success_warp('logout success')

其余的内容便不再赘述,具体的代码实现也没有什么难懂的地方,也没什么讲解的必要。

代码复用部分

本次项目我们主要复用的是前端部分的代码,并在其基础上进行了优化。

可以说本次结对编程,我的队友负责前端部分,因为复用的是我个人项目时的前端代码,所以我们采用的是React这样的技术。我的队友对于现在前端工程化的方法有了很大的理解,对于前端工作流的使用也初步进行了入门,对于流行的MVVM模型有了深入的理解。

接下来举一个React的Context的例子说明是怎么进行代码复用的:

// 个人项目代码
import React, {createContext, useState} from 'react';

export const TypeContext = createContext(null);

export const TypeProvider = props => {
  let [userType, setUserType] = useState({
    name: '张三1',
    type: 1
  });

  return (
    <TypeContext.Provider value={{userType, setUserType}}>
      {props.children}
    </TypeContext.Provider>
  )
};

export const TypeConsumer = TypeContext.Consumer;

//结对项目
import React, {createContext, useState} from 'react';

export const UserContext = createContext(null);

export const TypeProvider = props => {
  const [user, setUser] = useState('');
  const [errorMessage, setErrorMessage] = useState('');

  return (
    <UserContext.Provider value={{user, setUser, errorMessage, setErrorMessage}}>
      {props.children}
    </UserContext.Provider>
  )
};

export const TypeConsumer = UserContext.Consumer;

可以看到两者的代码基本上是一致的,只是我们所需要共享的数据不太一样,所以对外提供了不同的Provide

有兴趣的可以了解一下React Hooks的原理和使用

部署部分

Docker

Docker是一个开放源代码软件项目,让应用程序部署在软件货柜下的工作可以自动化进行,借此在Linux操作系统上,提供一个额外的软件抽象层,以及操作系统层虚拟化的自动管理机制。 Docker利用Linux核心中的资源分离机制,例如cgroups,以及Linux核心名字空间,来创建独立的容器。

我们的后端项目即采用Docker进行部署,具体的命令等大家可以查看Docker官网,下面给出Dockerfile:

# 基础镜像
FROM python:3.7

WORKDIR /app

ADD . /app

RUN pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple

CMD ["gunicorn", "main:app", "-c", "gunicorn.conf.py"]

Nginx

Nginx是异步框架的网页服务器,也可以用作反向代理、负载平衡器和HTTP缓存。该软件由伊戈尔·赛索耶夫创建并于2004年首次公开发布。 2011年成立同名公司以提供支持。2019年3月11日,Nginx公司被F5 Networks以6.7亿美元收购。 Nginx是免费的开源软件,根据类BSD许可证的条款发布。

我们的服务器只在443、80两个端口运行,其余的部署通过Nginx反代进行:

#PROXY-START/pair
location /pair
{
    expires 12h;
    if ($request_uri ~* "(php|jsp|cgi|asp|aspx)")
    {
         expires 0;
    }
    proxy_pass http://内网IP:6000/;
    proxy_set_header Host localhost;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header REMOTE-HOST $remote_addr;
    
    add_header X-Cache $upstream_cache_status;
    add_header Cache-Control no-store;

    proxy_cache cache_one;
    proxy_cache_key $host$uri$is_args$args;
    proxy_cache_valid 200 304 301 302 1m;
}

#PROXY-END/pair

注意其中因为使用了Docker不可以使用localhost,必须使用内网IP,记得作为API服务器应该设置不开启浏览器缓存。

猜你喜欢

转载自www.cnblogs.com/wangjq4214/p/11601388.html