从头完成一个restful API 服务(续)

简介: 从头完成一个restful API 服务(续)

上次我们一起完成了一个初级的API服务器的搭建,今天来给它增加点新功能,要看前面内容的,戳这里

01.完善设计

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

02.测试 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就好了。

03.前端代码

前端代码使用 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 += '<img src="' + res['p_url'] + '" width="100">';
        $('#result').html(result);
    }
    );
}
</script>

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

04. 后端代码

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

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})

05. 最终效果

最后的效果如下

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

06. 任重道远

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

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

相关文章
|
25天前
|
API 数据库 数据安全/隐私保护
利用Django框架构建高效后端API服务
本文将介绍如何利用Django框架构建高效的后端API服务。通过深入分析Django框架的特性和优势,结合实际案例,探讨了如何利用Django提供的强大功能来构建高性能、可扩展的后端服务。同时,还对Django框架在后端开发中的一些常见问题进行了解决方案的探讨,并提出了一些建设性的建议。
40 3
|
4天前
|
安全 Java API
RESTful API设计与实现:Java后台开发指南
【4月更文挑战第15天】本文介绍了如何使用Java开发RESTful API,重点是Spring Boot框架和Spring MVC。遵循无状态、统一接口、资源标识和JSON数据格式的设计原则,通过创建控制器处理HTTP请求,如示例中的用户管理操作。此外,文章还提及数据绑定、验证、异常处理和跨域支持。最后,提出了版本控制、安全性、文档测试以及限流和缓存的最佳实践,以确保API的稳定、安全和高效。
|
7天前
|
小程序 前端开发 API
小程序全栈开发中的RESTful API设计
【4月更文挑战第12天】本文探讨了小程序全栈开发中的RESTful API设计,旨在帮助开发者理解和掌握相关技术。RESTful API基于REST架构风格,利用HTTP协议进行数据交互,遵循URI、客户端-服务器架构、无状态通信、标准HTTP方法和资源表述等原则。在小程序开发中,通过资源建模、设计API接口、定义资源表述及实现接口,实现前后端高效分离,提升开发效率和代码质量。小程序前端利用微信API与后端交互,确保数据流通。掌握这些实践将优化小程序全栈开发。
|
16天前
|
前端开发 Java API
构建RESTful API:Java中的RESTful服务开发
【4月更文挑战第3天】本文介绍了在Java环境中构建RESTful API的重要性及方法。遵循REST原则,利用HTTP方法处理资源,实现CRUD操作。在Java中,常用框架如Spring MVC简化了RESTful服务开发,包括定义资源、设计表示层、实现CRUD、考虑安全性、文档和测试。通过Spring MVC示例展示了创建RESTful服务的步骤,强调了其在现代Web服务开发中的关键角色,有助于提升互操作性和用户体验。
构建RESTful API:Java中的RESTful服务开发
|
20天前
|
XML JSON 安全
谈谈你对RESTful API设计的理解和实践。
RESTful API是基于HTTP协议的接口设计,通过URI标识资源,利用GET、POST、PUT、DELETE等方法操作资源。设计注重无状态、一致性、分层、错误处理、版本控制、文档、安全和测试,确保易用、可扩展和安全。例如,`/users/{id}`用于用户管理,使用JSON或XML交换数据,提升系统互操作性和可维护性。
14 4
|
22天前
|
安全 API 开发者
构建高效可扩展的RESTful API服务
在数字化转型的浪潮中,构建一个高效、可扩展且易于维护的后端API服务是企业竞争力的关键。本文将深入探讨如何利用现代后端技术栈实现RESTful API服务的优化,包括代码结构设计、性能调优、安全性强化以及微服务架构的应用。我们将通过实践案例分析,揭示后端开发的最佳实践,帮助开发者提升系统的响应速度和处理能力,同时确保服务的高可用性和安全。
25 3
|
29天前
|
缓存 前端开发 API
构建高效可扩展的RESTful API:后端开发的最佳实践
【2月更文挑战第30天】 在现代Web应用和服务端架构中,RESTful API已成为连接前端与后端、实现服务间通信的重要接口。本文将探讨构建一个高效且可扩展的RESTful API的关键步骤和最佳实践,包括设计原则、性能优化、安全性考虑以及错误处理机制。通过这些实践,开发者可以确保API的健壮性、易用性和未来的可维护性。
|
JSON API PHP
CI中如何保护RESTful API
步骤5 保护RESTful API   为了保护RESTful API,可以在application/config/rest.php中设置安全保护级别,如下所示: $config['rest_auth'] = 'basic';    其中保护级别有如下设置:   None:任何人都...
904 0
|
10天前
|
缓存 前端开发 API
API接口封装系列
API(Application Programming Interface)接口封装是将系统内部的功能封装成可复用的程序接口并向外部提供,以便其他系统调用和使用这些功能,通过这种方式实现系统之间的通信和协作。下面将介绍API接口封装的一些关键步骤和注意事项。
|
17天前
|
监控 前端开发 JavaScript
实战篇:商品API接口在跨平台销售中的有效运用与案例解析
随着电子商务的蓬勃发展,企业为了扩大市场覆盖面,经常需要在多个在线平台上展示和销售产品。然而,手工管理多个平台的库存、价格、商品描述等信息既耗时又容易出错。商品API接口在这一背景下显得尤为重要,它能够帮助企业在不同的销售平台之间实现商品信息的高效同步和管理。本文将通过具体的淘宝API接口使用案例,展示如何在跨平台销售中有效利用商品API接口,以及如何通过代码实现数据的统一管理。