JSON

求助关于restfull api接口几个问题

字号+ 作者:H5之家 来源:H5之家 2017-06-08 15:04 我要评论( )

class User(db.Model): __tablename__ = users id = db.Column(db.Integer, primary_key=True) email = db.Column(db.String(64), unique=True, index=True) use

class User(db.Model): __tablename__ = 'users' id = db.Column(db.Integer, primary_key=True) email = db.Column(db.String(64), unique=True, index=True) username = db.Column(db.String(64), unique=True, index=True) role_id = db.Column(db.Integer, db.ForeignKey('roles.id')) password_hash = db.Column(db.String(128)) confirmed = db.Column(db.Boolean, default=False) name = db.Column(db.String(64)) location = db.Column(db.String(64)) about_me = db.Column(db.Text()) member_since = db.Column(db.DateTime(), default=datetime.utcnow) last_seen = db.Column(db.DateTime(), default=datetime.utcnow) avatar_hash = db.Column(db.String(32)) posts = db.relationship('Post', backref='author', lazy='dynamic') comments = db.relationship('Comment', backref='author', lazy='dynamic') def to_json(self): json_user = { 'url': url_for('api.get_post', id=self.id, _external=True), 'username': self.username, 'member_since': self.member_since, 'last_seen': self.last_seen, 'posts': url_for('api.get_user_posts', id=self.id, _external=True), 'post_count': self.posts.count() } return json_user class Post(db.Model): __tablename__ = 'posts' id = db.Column(db.Integer, primary_key=True) body = db.Column(db.Text) body_html = db.Column(db.Text) timestamp = db.Column(db.DateTime, index=True, default=datetime.utcnow) author_id = db.Column(db.Integer, db.ForeignKey('users.id')) comments = db.relationship('Comment', backref='post', lazy='dynamic') def to_json(self): json_post = { 'url': url_for('api.get_post', id=self.id, _external=True), 'body': self.body, 'body_html': self.body_html, 'timestamp': self.timestamp, 'author': url_for('api.get_user', id=self.author_id, _external=True), 'comments': url_for('api.get_post_comments', id=self.id, _external=True), 'comment_count': self.comments.count() } return json_post

2个类的定义如上,然后,假设现在需要获取设计两个接口:

  • 获取某个文章详细信息的接口。
  • 获取某个人发表的文章详细信息。
    我看到很多教程都是类似这样设计的:
  • @api.route('/posts/<int:id>') def get_post(id): post = Post.query.get_or_404(id) return jsonify(post.to_json()) @api.route('/users/<int:id>/posts/') def get_user_posts(id): user = User.query.get_or_404(id) page = request.args.get('page', 1, type=int) pagination = user.posts.order_by(Post.timestamp.desc()).paginate( page, per_page=current_app.config['FLASKY_POSTS_PER_PAGE'], error_out=False) posts = pagination.items prev = None if pagination.has_prev: prev = url_for('api.get_posts', page=page-1, _external=True) next = None if pagination.has_next: next = url_for('api.get_posts', page=page+1, _external=True) return jsonify({ 'posts': [post.to_json() for post in posts], 'prev': prev, 'next': next, 'count': pagination.total })

    对于接口返回的数据我有几个疑问:
    1:为什么很多详细信息都是返回URL而不是实体。
    比如:Class User类的to_json()方法为什么不像这样设计?

    def to_json(self): json_user = { 'url': url_for('api.get_post', id=self.id, _external=True), 'username': self.username, 'member_since': self.member_since, 'last_seen': self.last_seen, 'posts': [post.to_json() for post in self.posts], 'post_count': self.posts.count() } return json_user

    2:如果要返回实体信息要怎么操作好?
    3:我在github中看到很多flsk开源的项目,里面序列化或者反序列化都是用类似上面to_json, to_dict实现的,包括很多教程都是这样设计的。这种方法,个人觉得对于Model有几十个属性就感觉很无力,有什么好的办法?

    按照自己对Restful的理解,接口是针对资源进行操作。github曾经设计API接口是针对单独的资源,而获取每个资源的接口,里面提供一些url,以便可以获取下一个,或者返回上一个资源。

    设计两个接口,一个针对user这个资源获取详细信息,另外一个针对post这个资源获取详细信息。
    其中在获取用户发布文章的详细信息的接口。涉及user和post两个资源。根据查询条件是先找到user,再通过user去找post。因此可以看成是获取user这个资源,而user里涵盖了post资源,因此post字段换成获取post详细信息的接口,以便逻辑继续进行。

    可以理解为一个资源就是一个表,一个接口只请求这个表的字段,至于外键字段的实体资源,则提供查询的url接口。抛开那些实体之间的join操作。

    看原来的设计,是获取user下某篇post的详细信息,关联了post_id,你改的那个是获取user的发布的post列表。

    直接查询实体返回即可。

    其实尽管restful的提出了很久,也有所谓很多实践。不同的人理解不一样,也没有比较统一的说法。github的api是一个比较好的例子。

    实际开发中,几乎是不可能设计这样针对单个资源,资源之间通过url获取的接口的。因为先阶段来说,客户端工程师都希望一个接口搞定所有需要的数据,才不会管你什么资源啊,实体啊。通常喜欢减少网络的请求,哪怕传输的数据变多。

    如果是自己想实现restful风格的程序,可以参考github的api。在工作中,估计没有人会让你这么做,客户端要求什么,就写什么,不需要纠结。

    玩蛇网文章,转载请注明出处和文章网址: []



    【 我要小额赞助,鼓励作者写出更好的教程↓↓↓

     

    1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

    相关文章
    • ElasticSearch教程(5)——关于动态Mapping和templates

      ElasticSearch教程(5)——关于动态Mapping和templates

      2017-05-29 14:00

    • 关于springMVC处理json数据教程

      关于springMVC处理json数据教程

      2017-05-16 17:08

    • 关于php处理JSON的有关问题

      关于php处理JSON的有关问题

      2017-05-12 15:17

    • 网站关于百度地图定位代码.doc

      网站关于百度地图定位代码.doc

      2017-05-03 11:05

    网友点评
    v