最近对API服务开始有了兴趣,于是用flask与redis做了一个玩一玩,同时也学习一下API服务的搭建与通过JavaScript调用方法。

做出来的成果在https://www.dogcraft.top/xxjj/。这个是完全采用前后端分离搞出来的,前端完全是静态html与JavaScript,后端的flask不提供任何页面,只通过json传递数据。还同时搞了一个简单的后台管理页面,同样是纯静态的HTML与JavaScript,可以完成对数据的写、改、删,查询功能没做。

因为数据量不大,不想用庞大的mySQL之类的,最后决定用redis作为数据库。真实情况是除了redis之外其他数据库不会用

先来看后端的redis与flask,这里主要使用了flask_redis 和 flask_restful两个主要的库,有了这两个,后端就变得十分简单了。flask_redis 这个就不用多说了,就是用python操纵redis数据库,基本上与通过命令行操纵redis大同小异。flask_restful是这个API服务的核心,但用法不复杂,api用到的对象都是从Resource里面继承来的,在新的对象里面重新定义getpost之类的方法就行了。最后在利用add_resource将api调用方法绑定到url就可以了。


#!python3

import os.path as op
import json
from flask import Flask, abort, redirect, render_template, request, url_for
from flask_redis import FlaskRedis
from flask import jsonify
import os
from flask import send_from_directory
import random
from flask_restful import reqparse, abort, Api, Resource

app = Flask(__name__)
api = Api(app)
app.config['REDIS_URL']="redis://:password@redisserver:[port]/1" #redis address
app.config['JSON_AS_ASCII'] = False #讲人话
rc=FlaskRedis(app,decode_responses=True) #讲UTF8
Apdog="dogdog" #API key

def ver(key):
    if key==Apdog:
        return "OK"
    else:
        return "Bad"

class Dog(Resource):
    def get(self):
        cu=rc.llen('yl')
        bbn=random.randint(0,cu-1)
        ddd=rc.lindex('yl',bbn)
        rc.incr("dognum")
        # print(json.loads(ddd))
        return jsonify({'id':bbn,'cnt':json.loads(ddd)})
    
    def post(self):
        et=request.form['key']
        # print(et)
        if ver(et)=="OK":
            ty=request.form['c']
            ty2=request.form['f']
            ty3=request.form['url']
            ssui=json.dumps({'c':ty,'f':ty2,'url':ty3},ensure_ascii=False)
            sio=rc.rpush('yl',ssui)
            ddd=rc.lindex('yl',sio-1)
            # print(ddd)
            return jsonify({'id':sio-1,'cnt':json.loads(ddd)})
            # pass
        else:
            return "APIkey error"
    
    def put(self):
        et=request.form['key']
        # print(et)
        if ver(et)=="OK":
            ty0=request.form['id']
            ty=request.form['c']
            ty2=request.form['f']
            ty3=request.form['url']
            ssui=json.dumps({'c':ty,'f':ty2,'url':ty3},ensure_ascii=False)
            ddd=rc.lset('yl',int(ty0),ssui)
            return jsonify(ddd)
        else:
            return "APIkey error"
        
    
    def delete(self):
        et=request.form['key']
        if ver(et)=="OK":
            ty0=request.form['id']
            print(ty0)
            ddd=rc.lindex('yl',int(ty0))
            sti=rc.lrem('yl',0,ddd)
            return jsonify(sti)
        else:
            return "APIkey error"


class AllDog(Resource):
    def get(self):
        cu=rc.llen('yl')
        sh=rc.lrange('yl',0,cu-1)
        tu=list(map(json.loads,sh))
        # print(tu[0])
        return jsonify(tu)
    pass

class Dogkey(Resource):
    def post(self):
        ty=request.form['key']
        print(ty)
        if ty==Apidog:
            return "OK"
        else:
            return "Bad"
    pass

class Dognum(Resource):
    def get(self):
        return rc.get("dognum")


api.add_resource(Dog, '/d')
api.add_resource(AllDog, '/ad')
api.add_resource(Dogkey, '/key')
api.add_resource(Dognum, '/n')

后端代码并不复杂,相对而言前端就会更复杂一点。具体是什么样子的,到相关网页右键开发者工具就知道了,这里将几个重要的。后端主要用到的库有jQuery和bootstrapt4,在后台管理界面还会用到了vue,都是通过cdn引入的,毕竟阿里云服务器限速1M(128kb/s)。虽然除了我没几个人看,但还是能快一点算一点吧。

下面这个是每隔一段时间就调用一次api的js代码,用了JavaScript,可以使“死”网页“活”起来。

由于用到了JavaScript加载异步资源,要特别注意跨域问题,在部署API服务的时候一定不要忘了。

    var jv;
    var fm;
    $(document).ready(function(){
        getjj();
        cg();
        setInterval(cg,7000);
});

function getjj() {
    $.get("https://api.dogcraft.top/api/d",function (data,status) {
        fm=data.cnt.f;
        jv=data.cnt.c;
        $("#jj").text(jv);
        $("#cc").text(fm);
    })
}

function getjj2(sdfu) {
    $.get("https://api.dogcraft.top/api/d",function (data,status) {
        fm=data.cnt.f;
        jv=data.cnt.c;
        sdfu();
    })
}

function cg() {
    getjj2(gtdog);
}
function gai() {
    //更换新的文字
    $("#jj").text(jv);
    $("#cc").text(fm);
    // console.log("o")
}
function gtdog() {
    //渐变效果
    $("#shu").fadeToggle(2000);
    setTimeout(gai,2000);//延时更换文字
    $("#shu").fadeToggle(2000);
}

上面这个的具体思路就是每隔一段时间就向API服务器发起一次请求,一旦get数据成功并存储到变量之中之后,就会让整个div渐变隐藏(设定渐变时间为2s),然后设置定时任务2s之后更换文字,渐变隐藏与显示这个命令是异步的,开始动作之后会马上执行下一句,所以要设置这2s的延迟时间,在完全淡出隐藏之后再更新文字。

后台管理页面的JavaScript与这里的大同小异,就是多了vue的双向绑定与几个表单,可以自行去相关页面查看。