分享一下声明式 API 的写法

2020-12-16 12:02:56 +08:00
 Joker123456789

通常一个 Controller 是以 class 的形式创建的,需要在里面注入 Service,写方法体,调用 Service 的方法,来完成数据交互。

而声明式 API 是将 class 变成一个 interface,节省了一些代码量,从而提高开发效率,同时因为这只是一个抽象方法,重新编写的成本极低,所以当不需要的时候 可以直接无脑删,不用担心后面又需要了咋办。

演示效果如下

假设现在有一个 Service,bean 名称为 aService,现在需要通过 Controller 来调用 aService 里面的 selectList 方法

@MarsApi(refBean="aService")
public interface TestApi {

	返回类型 selectList(TestDTO testDTO);
}

当我们请求这个接口的时候,他会自动调用 aService 里面的 selectList 方法,并将返回值转成 json 返回。

如果我想在这个 API 里面 调用 bService 里的方法咋办?

@MarsApi(refBean="aService")
public interface TestApi {

	// 这个注解可以覆盖类上面的 refBean
	@MarsReference(beanName = "bService")
	返回类型 selectList(TestDTO testDTO);
}

我不想把 API 里的方法名称 写的跟 Service 一样咋办?

@MarsApi(refBean="aService")
public interface TestApi {

	@MarsReference(refName = "要调用的 service 的方法名")
	返回类型 selectList(TestDTO testDTO);
}

我可以不调用方法,只返回 Service 里面的一个属性值吗?

@MarsApi(refBean="aService")
public interface TestApi {

	@MarsReference(refName = "要调用的属性名", refType = RefType.PROPERTY)
	返回类型 selectList(TestDTO testDTO);
}

想对参数做校验咋办,这都没方法体了,难道写在 Service ?

在接参对象的属性上添加 @MarsDataCheck 注解接口

// 不可为空,且长度在 2-3 位
@MarsDataCheck(notNull = true,maxLength = 3L,minLength = 2L, msg = "id 不可为空且长度必须在 2-3 位之间")
private Integer id;

// 正则校验
@MarsDataCheck(reg = "^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,12}$",msg = "密码不可以为空且必须是 6-12 位数字字母组合")
private String password;

不同的接口对参数的校验需求不一样,这种校验方式在遇到两个接口用同一个接参对象时会不会就 GG 了

不会,加一个 apis 属性即可搞定

public class ExpVO {

    /* 
     * expGetRequest 和 expPostRequest 两个接口都不允许 name 为空
     * 只需要在 apis 属性里配置这两个接口即可,但是由于他们都是 exp 开头的
     * 所以用通配符即可
     */
    @MarsDataCheck(notNull = true, msg = "名称不可以为空", apis={"exp*"})
    private String name;

    /* 
     * saveRequest 和 expPostRequest 两个接口都不允许 address 为空
     * 只需要在 apis 属性里配置这两个接口即可
     */
    @MarsDataCheck(notNull = true, msg = "地址不可以为空", apis={"expPostRequest","saveRequest"})
    private String address;

}

想要给 API 加 try-catch,让它在异常的时候,还可以正常返回 json 咋办?

这个不用使用者关心了,因为这个框架是纯粹面向前后端分离的,所以无论出现什么情况,前端都可以收到 json, 假如出异常了,那么前端会收到这样一个 json

{error_code:500, error_info:"异常提示"}

我还是有点顾虑,不敢尝试这种写法

没关系,我们兼容常规的 Controller 写法

@MarsApi
public class DemoController {

	@MarsWrite("userInfoServiceImpl")
	private UserInfoService userInfoService;

	public String demo(UserInfoDTO userInfoDTO, HttpMarsRequest request){
		return "";
	}
}

有点意思,我想再多了解一点

官网地址:http://mars-framework.com/

4554 次点击
所在节点    Java
43 条回复
11ssss
2020-12-16 15:17:47 +08:00
‘我之所以声明是正儿八经的开源项目’ 路过,GitHub 开源协议不加一下吗?
Joker123456789
2020-12-16 15:19:03 +08:00
@11ssss 你应该没认真看,或者你的网卡了 没加载出来
efaun
2020-12-16 15:21:42 +08:00
@Joker123456789 #20 哎,可怜人,其他项目都会遵守规则发推广节点,只有你,我说了三次你还不知道错在哪里

呜呼哀哉!
11ssss
2020-12-16 15:22:40 +08:00
@Joker123456789 看错了 当我没说
Joker123456789
2020-12-16 15:25:00 +08:00
@efaun 那你又知道自己错在哪了吗? 呜呼哀哉你 MB 啊。真当自己是上帝啊,我做什么轮得到你指指点点? 赶紧滚吧,有意见就举报一波,让管理员来删帖,比跟我 BB,看你来气。
shuige
2020-12-16 15:43:49 +08:00
楼下吃瓜
rocbomb
2020-12-16 15:47:31 +08:00
这个。。。ASP.NET Core MVC 是不是有点像
liuhuansir
2020-12-16 15:47:42 +08:00
吃瓜,看看最后怎么处理这个帖子,劝 LZ 还是别爆粗口,注意下素质
qwertyzzz
2020-12-16 16:22:39 +08:00
吃瓜 我觉得这还好吧 没那么多推广味 发哪我也不那么在意 不看 x 了得了 没必要当个圣母指指点点
Joker123456789
2020-12-16 16:23:14 +08:00
@liuhuansir 谢谢提醒,但是没办法,直性子被喷了忍不住要反击。
shenlanAZ
2020-12-16 16:23:35 +08:00
相当于把 controller 层砍掉了,如果 controller 需要根据参数来调用不同的 service 乃至不同的方法 这样就很难实现了。

另外 refBean 为什么要 Bean 名称,既然已经确认类型了 为什么不用 IxxService.class ?我为什么还要手动拼出来 bean 名称 还是说你框架可以帮我自动取到 bean 名称。

另外一点 在异常的时候返回 我比较关心你那个 error_code 为 500 的时候 http status 是不是 500,error_code 是否可以定制,如果不可定制 那和 http status 重复的意义在哪里?
Kirsk
2020-12-16 17:28:39 +08:00
@Joker123456789 如果你认为使用你的东西要仔细阅读文档 而不是像多数人使用 spring 时一些约定俗成的写法 那 ok 如果不是我怎么知道你封装的注解有什么操作 而且你这个设计等于在 spring 上再自己封装一层 你能给使用者带来更高效的开发吗 如果我不用你框架了 是不是全部爆红? 影响到整体项目没? 打个比方 我从 orm1 框架换 orm2 他影响的范围是数据存取部分 如果 orm12 都遵守一样的范式协议影响更小 你说你能直接删 你的返回单个参数涉及业务逻辑没? 参数校验规则涉及没 你见过哪个框架是这么设计的 我把框架删了要不要补大量的逻辑?
mmrx
2020-12-16 18:42:18 +08:00
spring boot 小白,我想问这个 interface 的写法兼容 Swagger 么,支持注解方式的跨域配置么
如果不支持,只能用你说的兼容常规 Controller 写法,那这个框架还有什么意义呢
Joker123456789
2020-12-16 19:53:48 +08:00
@mmrx swagger 是 自动生成文档的,不是硬需求,支不支持看后面规划。 跨域问题,这个肯定是支持的,不然我敢纯粹面向前后端分离吗
Joker123456789
2020-12-16 19:55:18 +08:00
@shenlanAZ 根据返回的数据,判断是否成功 并不难吧, 为什么必须要 http status 告诉你, 我不太理解。
Joker123456789
2020-12-16 19:57:24 +08:00
@Kirsk 这跟 spring 一点关系都没, 而且我确实不是按照约定俗成的规则写的。

不会出现报红,因为这不是渐进式框架, 使用者要么从创建项目开始就用,要么永远不用。
Joker123456789
2020-12-16 20:00:32 +08:00
@shenlanAZ 而且 现在流行的做法 不都是 catch 里返回 json 吗,或者用异常监听, 就是为了避免 500 啊
Joker123456789
2020-12-16 20:03:08 +08:00
@Kirsk 最后,我说的删 不是指删框架, 你可能没看懂, 又或者是我没写明白
xuanbg
2020-12-16 20:19:29 +08:00
我今天下午 40 多个接口居然一气呵成写完鸟……,中间还玩了几把游戏,这效率还要什么自行车
mmrx
2020-12-17 10:04:10 +08:00
@Joker123456789 Swagger 目前我接触到的基本上都是用的,输出 API 文档目前应该就是硬需求了吧..
另外这些基础的注解配置我专门看了一下你官网的文档,貌似都么有提及,都是在讲一些新的,不一样的点。个人感觉没有兼容说明对于大多数人都是比较劝退的,因为没多少人原因当小白鼠

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

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

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

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

© 2021 V2EX