Java 设计JSON API时的内部对象表示

Java 设计JSON API时的内部对象表示,java,json,web-services,jackson,Java,Json,Web Services,Jackson,我有一个物体设计的问题 我正在用Java构建json api。我的系统使用pojo表示json对象,并使用Jackson将它们从json转换为pojo。每个对象需要在不同的上下文中采用不同的形式,我无法决定是创建一组单独的类,每个上下文一个,还是尝试使一个公共类在所有情况下都工作 让我举一个具体的例子 该系统具有多个用户。api有一个用于添加、修改和删除用户的服务。数据库中有一个用户表。数据库记录如下所示: { id: 123, // autoincrement name: "Bob",

我有一个物体设计的问题

我正在用Java构建json api。我的系统使用pojo表示json对象,并使用Jackson将它们从json转换为pojo。每个对象需要在不同的上下文中采用不同的形式,我无法决定是创建一组单独的类,每个上下文一个,还是尝试使一个公共类在所有情况下都工作

让我举一个具体的例子

该系统具有多个用户。api有一个用于添加、修改和删除用户的服务。数据库中有一个用户表。数据库记录如下所示:

{
  id: 123, // autoincrement
  name: "Bob",
  passwordHash: "random string",
  unmodifiable: "some string"
}
{
    "status": "ERROR",
    "errors": [
        {
            "errorType": 1001,
            "message": "Id field is not allowed in POST request."
        }
    ]
}
{
    "status": "SUCCESS",
    "warnings": [
        "Id field was omitted."
    ]
}
发布/添加用户时,pojo不应包含id,因为id是自动生成的。您还希望能够包含一个密码,该密码将被散列并存储在数据库中

放置/更新用户时,pojo不应包含不可修改字段,但必须包含id,以便知道要修改的用户

获取/检索用户时,应获取除passwordHash之外的所有字段

因此,表示用户的pojo具有不同的属性,这取决于您是添加、更新还是检索用户。它在数据库中具有不同的属性

那么,我应该在我的系统中创建四个不同的POJO并在它们之间进行翻译吗?或者创建一个用户类,并尝试使用Jackson视图或其他机制使其在不同的环境中看起来不同


我发现后一种方法真的很难管理。

在我看来,您应该只创建一个
POJO
-
User
,它具有所有需要的属性。现在,您应该决定您的
API
是严格的还是宽松的。如果您的
API
是严格的,那么当它接收到错误的
JSON
数据时,它应该返回错误。在宽松版本中,API可以跳过多余(不必要)的属性

在提供示例之前,让我将“passwordHash”属性更改为“password”

添加新用户/帖子
JSON
来自客户端的数据:

{
  id: 123,
  name: "Bob",
  password: "random string",
  unmodifiable: "some string"
}
严格版本可以返回如下内容:

{
  id: 123, // autoincrement
  name: "Bob",
  passwordHash: "random string",
  unmodifiable: "some string"
}
{
    "status": "ERROR",
    "errors": [
        {
            "errorType": 1001,
            "message": "Id field is not allowed in POST request."
        }
    ]
}
{
    "status": "SUCCESS",
    "warnings": [
        "Id field was omitted."
    ]
}
宽大版本可以返回如下内容:

{
  id: 123, // autoincrement
  name: "Bob",
  passwordHash: "random string",
  unmodifiable: "some string"
}
{
    "status": "ERROR",
    "errors": [
        {
            "errorType": 1001,
            "message": "Id field is not allowed in POST request."
        }
    ]
}
{
    "status": "SUCCESS",
    "warnings": [
        "Id field was omitted."
    ]
}

对于每个
CRUD
方法,您可以编写一组单元测试,其中包含您选择的方法以及允许和不允许的信息。

为什么要使用POJO?只需使用Maps.pojo就可以了,因为它们可以很容易地记录web服务的输入和输出。我同意这一点。严格指定数据模式(例如使用XML模式甚至JSON模式)的一个问题是,验证决策不是数据固有的,而是过程的一部分。验证取决于您对数据所做的操作。因此,在这种情况下,最好将验证放在流程级别(API)而不是数据级别(POJO)。波斯特尔定律在这里很适用。