文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

从头完成一个restful API 服务

2024-12-13 15:50

关注

1.完善设计

在上次的设计当中,我们定义了三张表,AdminUser,用来作为调用 API 鉴权用户,User,用来作为存储普通用户使用,Picture,用来作为存储用户上传的图片。但是当时只是实现了 AdminUser 的相关功能,而 User 和 Picture 还没有真正的关联起来,这次就把它们完善起来

2.测试 server

为了方便测试,我们这里写了一个简单的测试 web server,用来在网页上向 API 服务器发请求。代码很简单,还是用 flask 来启动 server,返回一个页面。

@app.route('/jsupload', methods=['POST', 'GET'])
def jsupload():
return render_template('js_upload.html')

而返回的这个页面也很简单,包含一个 form,用来提交数据的。

<form id= "uploadForm">
<p >指定用户名: <input type="text" name="filename" value= "" id="UID"/>p>
<p >上传文件: <input type="file" name="file" id="PID"/>p>
<input type="button" value="上传" onclick="upload()" />
form>

服务起来之后大概是这样的

不要嫌弃它丑,功能够了就行了。

这样一个简单的测试server就好了。

3.前端代码

前端代码使用 Ajax 来提交数据和回显数据

<script type="text/javascript">
function upload(){
//var formData = new FormData($( "#uploadForm" )[0]);
var img_file = document.getElementById("PID");
var fileObj = img_file.files[0];
var formData = new FormData();
formData.append("UID", $("#UID").val());
formData.append("PID", fileObj);

$.ajax({
method: "POST",
url: "http://127.0.0.1:9980/api/test",
timeout: 10000,
data: formData,
async: false,
headers: {"client-type":"platform",},
dataType: "json",
contentType:false,
processData:false,//数据不做预处理
success: function(res) {
return;
},
error: function(e){
alert(e.msg);

}
}).done(function(res){
var result = '';
var result1 = '';
result += ' + res['p_url'] + '" width="100">';
$('#result').html(result);
}
);
}

script>

代码都是比较基础的,定位元素,调用函数,说下这里的 url,那个就是我在本地启动的 API server 的地址喽。同时这里还在监听服务器的返回,获取到返回的 p_url,来显示图片。

4. 后端代码

首先判断下前端传的是否是图片文件,如果不是直接返回错误

if 'PID' not in request.files:
return jsonify({'code': -1, 'filename': '', 'msg': 'please select one picture to upload'})

如果判断通过,就获取图片和用户名称

user = request.form.get('UID')
f = request.files['PID']

然后在本地创建目录用于保存图片,并且着手处理 User 和 Picture 的关系

basepwd = os.getcwd()
pwd = os.path.join(basepwd, r'app')
tmp_path = os.path.join(pwd, r'static/%s' % user)
new_filename = str(time.time()) + '.' + f.filename.split('.')[1]
if not os.path.exists(tmp_path):
os.makedirs(tmp_path)
upload_path = os.path.join(tmp_path, secure_filename(new_filename))
f.save(upload_path)
if User.query.filter_by(username=user).first():
u = User.query.filter_by(username=user).first()
u.picture_count += 1
p = Picture(picture_name=user, picture=upload_path, picture_id=u.id)
db.session.add(u)
db.session.add(p)
db.session.commit()

如果不存在目录则创建,并且保存图片。如果用户存在于数据库中,那么 picture_count 加1,同时更新 Picture 表,关联 picture_id 为 user_id。

如果用户不存在,那么先插入用户,提交,然后再更新 Picture 表

newu = User(username=user)
db.session.add(newu)
db.session.commit()
newp = Picture(picture_name=user, picture=upload_path, picture_id=newu.id)
db.session.add(newp)
db.session.commit()

最后API返回p_url用于前端web展示

return jsonify({"p_url": 'http://127.0.0.1:9980/static/%s/' % user + new_filename})

5. 最终效果

最后的效果如下

同时在项目的 static 目录下,会产生每个用户的图片,因为图片的命名都使用了 time.time(),也就不存在重名覆盖的问题啦

6. 任重道远

这次的完善就到这里了,不过程序还是有很多问题的,比如已知的问题就有如果在web端不填写名字或者不选择图片,都会产生一些问题;同时还可以增加一些接口,比如获取用户所有图片等待,这些都留到后面再说吧

还有个严峻的问题,就是每次本地调测好之后,都要手动同步代码到远程服务器,非常之麻烦,虽然目前项目很小,但是 CI 还是很有必要的,后面就来聊聊怎么结合 GitHub 做持续集成吧

完整代码看这里: https://github.com/zhouwei713/mini_api

来源:萝卜大杂烩内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯