分享一下声明式 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 条回复
lwq84510
2020-12-16 12:44:01 +08:00
@Livid 这历史发帖算变相推广了吧
SorcererXW
2020-12-16 12:50:43 +08:00
你需要 GraphQL
Joker123456789
2020-12-16 12:57:15 +08:00
@SorcererXW 跟我这个完全不搭噶, 拿其他项目压我,也要压在点上啊。 弄个完全不搭噶的 干嘛。
Joker123456789
2020-12-16 13:08:11 +08:00
@lwq84510

你能找到 跟这一模一样的历史帖子,我直播吃屎。

还有,这里都是程序员,我推的也是一个正儿八经的开源项目,开源,开源。 所以你有什么无法接受的?

不喜欢不用不就好了。
Kirsk
2020-12-16 13:54:01 +08:00
没有用过你项目的 这什么奇葩写法 调用顺序是什么 用过 spring 的 哦 我去找声明 bean 注入的地方 做框架是要解耦 不解耦要他干嘛 你这个侵入程度很明显 只适合自己内部用 比 autowired 更费心力
eric96
2020-12-16 14:28:10 +08:00
你们怎么会有这么多奇怪的想法
efaun
2020-12-16 14:29:53 +08:00
@Joker123456789 #4 开源不是挡箭牌,只要帖子里有外部链接且利益相关的,一律算推广
disk
2020-12-16 14:31:17 +08:00
如果接口和服务是绑定的,用这个注解可以省些代码量。解耦的话完全就不合适这种。
Joker123456789
2020-12-16 14:44:02 +08:00
@efaun

是算推广啊,不然我分享出来干嘛? 推上 github,静静等待,一切看缘分不是更好。

而且谁写东西不是为了利益的? 我还真不信有这种人, 不为推广,不为让更多人看到,那么放自己网盘加密不是更好。

我之所以声明是正儿八经的开源项目,不是为了当挡箭牌,只是为了明确调性,技术社区发技术帖子,我个人认为完全没问题, 我之所以有罪 就是因为这个项目是我做的,如果不是我做的,估计就没人说啥了。
jaylee4869
2020-12-16 14:46:14 +08:00
Java 开发者使用声明式 API 无非就是注解。
https://lawrenceli.me/blog/declarative-programming
Joker123456789
2020-12-16 14:46:16 +08:00
@Kirsk controller 调用 service 要什么顺序? 不就是调用 service 里的一个方法就好了吗?

你后面几句 我一句都没听懂,可否详细说明一下?
Joker123456789
2020-12-16 14:48:24 +08:00
@jaylee4869

针对你的回帖,我想说一句 [AOP 无非就是动态代理,IOC 无非就是反射赋值]

然后,你给我的连接里面的声明式 API 应该仅仅只是跟我的说法重名了,但不是同一种东西。
efaun
2020-12-16 14:49:34 +08:00
@Joker123456789 #9 “你之所以有罪 就是因为”你的贴子应该发在了 java 节点而不是推广节点,懂?
Joker123456789
2020-12-16 14:52:15 +08:00
@efaun 如果不是我做的呢?? 你还会说这句话吗? 如果我介绍的是 spring 里的 某个技术点呢?

还有,这整篇文章都是在正儿八经的介绍这个结束点啊,你看到什么推广的字眼了没? 不就因为这个项目是我做的,你们很排斥嘛。
zhuangzhuang1988
2020-12-16 14:54:52 +08:00
不喜欢写一堆注解来做 dependency-injection
还是 asp.net 来得好,
https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-5.0
efaun
2020-12-16 14:57:08 +08:00
@Joker123456789 #14 看不懂人话?我第一句就说了“只要帖子里有外部链接且利益相关的,一律算推广”,第二句也说了“你的贴子应该发在了 java 节点而不是推广节点”,全篇跟是不是你做的有关系吗?你算什么东西?不是你做的几个 star 怎样,是你做的几万个 star 又怎样?推广就应该发在推广节点,你自己的回复也承认了这是推广,现在又翻脸不认?什么玩意
brezp
2020-12-16 15:00:00 +08:00
点进去看了下, 野心很大啊, 想自己再造一个 spring?
Joker123456789
2020-12-16 15:02:57 +08:00
@efaun 那你又算什么东西? 轮得到你指指点点?? 我发个技术文章关你屁事啊? 不喜欢就滚蛋,我求你用还是怎么着?

你说我该发到推广节点,不就是因为 [这是我做的吗?] 除此之外还有什么原因吗?? 你从我的文章里一五一十指出问题来,去指啊。

如果我的文章是 [分享一下 AOP 的写法] 你还会跟我说这些屁话吗?

连你自己为什么要骂我的原因 自己心里都没数吗??

是你莫名其妙的出来一顿乱喷,还好意思对我发火,什么玩意。
efaun
2020-12-16 15:09:48 +08:00
@Joker123456789 #18 两次好言好语回复不看,非要被喷才舒服,看来你现在还是不知道自己的项目为什么不被 V2EX 的人看好,哎,可怜、可悲、可叹,希望其他开源项目没事🙏
Joker123456789
2020-12-16 15:14:34 +08:00
@efaun 好言好语??? 哈哈哈 XSWL, 知道自己理亏了 就开始扯别的了? 还希望别的没事,别的项目 一样被你们这种人喷。 在这装什么无辜呢

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

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

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

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

© 2021 V2EX