SpringBoot Rest 最佳实践的一些疑问

2021-06-28 10:17:07 +08:00
 LLaMA2

不得已要做后端开发,于是按照官方指导使用 SrpingBoot Web + JPA + Rest

写起来比较愉快,

domain 如下:


@Entity
@Getter
@Setter
public class Account {

    @Id
    @Column(nullable = false, updatable = false)
    @SequenceGenerator(
            name = "account_sequence",
            sequenceName = "account_sequence",
            allocationSize = 1,
            initialValue = 10000
    )
    @GeneratedValue(
            strategy = GenerationType.SEQUENCE,
            generator = "account_sequence"
    )
    private Long id;

    @Column(nullable = false, unique = true, updatable = false)
    private String account;

    @Column(nullable = false)
    private String passwd;

    @Column
    private String salt;

    @Column
    private String nonce;

    @OneToOne
    @JoinColumn(nullable = false, updatable = false, unique = true)
    private Member member;
    
    // 偷个懒,投影直接下载这个类内部了
    @Projection(name = "accountDTO", types = Account.class)
    public interface AccountDTO {
        String getAccount();
        String getSalt();
    }
}

仓储接口

@RepositoryRestResource(excerptProjection = Account.AccountDTO.class)
public interface AccountRepository extends JpaRepository<Account, Long> {}

此时启动工程,http://127.0.0.1/accounts接口中 account 的属性 passwd 由于投影的缘故没显示 大约是这个样子,这符合我的预期,我很欣慰!

{
    "_embedded": {
        "accounts": [
            {
                "account": "1008610010",
                "salt": "xxxxx",
                // 这里的 passwd 和 nonce 都没有了
                "_links": {
                    "self": {
                        "href": "http://127.0.0.1/accounts/10000"
                    },
                    "account": {
                        "href": "http://127.0.0.1/accounts/10000{?projection}",
                        "templated": true
                    },
                    "member": {
                        "href": "http://127.0.0.1/accounts/10000/member"
                    }
                }
            }
        ]
    },
    "_links": {
        "self": {
            "href": "http://127.0.0.1/accounts"
        },
        "profile": {
            "href": "http://127.0.0.1/profile/accounts"
        }
    },
    "page": {
        "size": 20,
        "totalElements": 1,
        "totalPages": 1,
        "number": 0
    }
}

此时调用http://127.0.0.1/accounts/10000,结果不该出现的 passwd 和 nonce 冒出了头。我很想跳起来对着他的狗头就是一脚。

{
    "account": "1008610010",
    "passwd": "999999",// <===========================这里
    "salt": "salt",   
    "nonce": "nonce",// <===========================这里
    "createAt": "2021-06-22T15:01:17.50913+08:00",
    "modifyAt": "2021-06-22T15:01:24.41396+08:00",
    "_links": {
        "self": {
            "href": "http://127.0.0.1/accounts/10000"
        },
        "account": {
            "href": "http://127.0.0.1/accounts/10000{?projection}",
            "templated": true
        },
        "member": {
            "href": "http://127.0.0.1/accounts/10000/member"
        }
    }
}

在此,征求广大外出务工人员,授我渔,喂我🐟!提供一些 SrpingBoot JPA REST 一些常用的套路,值得细读和探讨的资料。

叩首!!!

1001 次点击
所在节点    问与答
3 条回复
wccc
2021-06-28 10:30:29 +08:00
dejavuwind
2021-06-29 11:06:10 +08:00
我选择手动 set null 或者 单独封 DTO 投影还没用过
试了一下,可以试试 http://127.0.0.1/accounts/10000?projection=accountDTO
LLaMA2
2021-06-30 16:40:46 +08:00
@dejavuwind 按照最佳实践的方式,不使用 spring-boot-starter-data-rest 的话,每个 DO 都会对应着一个 DTO,这样可以在 DTO 中隐藏不不必要的细节,且 DTO 做成更符合 VO 的方式,这样 DO 不用添加一些和 DB 无关的注解,类似于 JsonIgnore 、JsonFormat 等,DTO 中的可以加上 Size Pattern 等注解,这样更符合最佳实践,不过加上了 spring-boot-starter-data-rest,一切都变得不可控且不易理解

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/786172

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX