在REST API建模对象继承 [英] Modeling Object Inheritance in a REST Api

查看:199
本文介绍了在REST API建模对象继承的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有,有一个用户对象和学生对象的应用程序。的部分的用户是学生。所有的学生都是用户。在数据库(Django的ORM为主),这是重新psented为学生表外键的用户表。

I have an application that has a User object and a Student object. Some users are students. All students are users. In the database (django-ORM based), this is represented as a Student table with a foreign-key to the User table.

我试图创建一个REST API,并在iOS应用的模型此API的对象层次。我无法决定如何建模。

I'm trying to create a REST API, and an object hierarchy in the iOS app that models this API. I'm having trouble deciding how to model this.

我想出的最好的是这样的:有一个用户模式在iOS上,有一个学生模型中的iOS从用户继承,并与更多的属性进行了扩展。然后,让接收来自服务器的JSON响应,并创建一个方法的或者的一个用户学生模式,取决于dictinoary。

The best I've come up with is this: Have a User model in iOS, have a Student model in iOS which inherits from User and extends it with more properties. Then, have a method which receives a JSON response from the server, and creates either a User or a Student model, depending on the dictinoary.

最后,服务器将需要总是给我的最具体类型。即,当我登录到服务器时,它会决定我是否是学生还是只是一个普通的用户,并且将返回我正确的字典。

Finally, the server will need to always give me the most specific type. I.e., when I log in to the server, it will decide whether I'm a student or just a regular user, and will return me the proper dictionary.

这听起来有点复杂。但是,任何其他方式,我认为它建模,例如更改数据库的布局方式,给了我一个设计,其中数据库是不知道的所有约束。例如,学生对象可以拥有的其他对象(e..g, homework_paper )。我可以用一个外键到用户对象而不是在学生的对象模型这一点,并说,学生简直就是用户的扩展。但随后的数据库不强制一个事实,即 homework_paper 必须由学生所拥有。

This sounds a little complicated. But any other way I've thought of modeling it, e.g. changing the way the database is laid out, gives me a design in which the database isn't aware of all the constraints. For example, Student objects are allowed to own other objects (e..g, homework_paper). I can model this with a foreign key to a User object instead of to the Student object, and say that the Student is simply an extension of the user. But then the database doesn't force the fact that a homework_paper has to be owned by a student.

有没有更好的办法来解决这个问题,我失踪?

Is there a better way to solve this problem that I'm missing?

推荐答案

有什么,说在你的UI层的类需要匹配1对1与您的域类。就像你的域类不必按照你的数据库表完全相同。

There is nothing that says the classes in your UI layer need to match 1-on-1 with your domain classes. Just like your domain classes do not have to follow your database tables exactly.

您可以把类的UI层的UI重新presentations为不同的组类。你需要的类,使您的UI的工作,或者用你的优势构架,而不在你的领域模型和/或数据库设计危及业务规则需要的。

You can think of the classes for your UI layer your UI representations as a different set of classes. Classes you needed to make your UI work, or needed to use a framework to your advantage without compromising the business rules in your domain model and/or database design.

您的用户UI类很可能是一个包装用户和学生域类的类。这将同时拥有用户和学生领域类的知识。然后由这个包装类实例化一个用户或学生。

Your User UI class could well be a class that wraps both user and student domain classes. It would have knowledge of both User and Student domain classes. It is then up to this wrapper class to instantiate either a User or Student.

另一种方法是作为一个具有相对于用户学生关系进行建模,而不是是。毕竟,你打算怎么办时,用户不仅可以是学生,但教师也是如此。例如,当一个老师在其他一些过程一个比他(她)教录取。通常,这些类型的关系的使用角色比为是关系更好建模。见Martin Fowler的关于与角色处理更多的信息。

Another approach would be to model the User-Student relation as a "has a" relation instead of a "is a". After all, what are you going to do when user's can not only be students but teachers as well. For example when a teacher enrolls in some other course than the one (s)he teaches. Usually, these kinds of relations are better modelled using Roles than as "is a" relations. See Martin Fowler for more info on Dealing with Roles.

在任何情况下,用户UI类将是您重新presentation的基础在你的REST实现,并填写在重新presentation多余的部分依赖于它是否是处理与用户或学生或 - 在基于角色的方法 - 即具有与它相关的东西的学生用户:

In any case, the User UI class would be the basis for your representation in your REST implementation and fill extra parts in that representation dependent on whether it is dealing with a user or a student or - in the role based approach - a user that has student stuff associated with it:

{
  "user": "/users/1234",
  "name": "Some non student's name",
  "stats": {
    ...
  }
}, 
{
  "user": "/users/4567",
  "name": "Some Student's name",
  "stats": {
    ...
  }
  "papers": [
    { "paperid": "/users/papers/111"
      ...
    },
    { "paperid": "/users/papers/222"
      ...
    },
    { "paperid": "/users/papers/333"
      ...
    }
  ]
}

编辑回应评论

该服务器具有无论如何决定,在一定程度上,除非你想有在URI级用户和学生之间的差异化的用户界面。我建议反对。它使用户界面不可用的。用户不感兴趣的实施细则,不希望与他们对质。

The server has to decide that anyway at some level, unless you want to have your UI differentiate between users and students at the URI level. Which I recommend AGAINST. It makes for unusable UI's. The user isn't interested in the implementation details and doesn't want to be confronted with them.

但是,没有,如果的是不会必要的。

But no, if's are not needed.

使用polymorfism你的优势。

Use polymorfism to your advantage.

服务器可以把polymorfism很好地利用其数据访问框架接收学生的实例,它检索由ID的所有用户。学生毕竟可以随时为用户引用。因此,服务器可以简单地忽略用户引用它从数据访问框架得到可能是一个学生的事实。当服务器真正需要做/添加特定学生的东西,它应该在派生类中这样做。

The server can put polymorfism to good use receiving a student instance from its data access framework for any user that it retrieves by id. Students after all can always be referenced as users. So the server can simply ignore the fact that the user reference it gets from the data access framework might be a student. When the server actually needs to do/add specific student stuff, it should do so in a derived class.

如果语句需要没有找到在任何地方使用。甚至在UI类。用户界面只需要知道用户参考接收也可能是一个学生,采取相应的行动。 preferably不受如果用户是学生(那被捆绑的用户界面的方式,深入到类层次结构),但如果IUSER工具IStudent :询问用户参考是否也实现学生接口,然后获取和使用该IStudent接口引用

No if statement needs to be used anywhere for this. Not even in the UI classes. The UI just needs to know that the User reference it receives could also be a Student and act accordingly. Preferably not by if User is Student (that would be tying the UI way to deeply to the class hierarchy), but by if IUser implements IStudent: asking the User reference whether it also implements the Student interface, and then getting and using that IStudent interface reference.

这篇关于在REST API建模对象继承的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆