在开发中,有些外部系统需要依赖我们系统的数据,如系统数据发生变更需要告知外部系统(外部系统可能有很多个),我们初步想用webhook的方式来实现,想知道webhook是怎么用的。怎么搭建需要什么技术
webhook 的概念很简单,webhook 就是一个简单的 HTTP 回调。当发生某些事情时,HTTP POST 调用的注册 URL 作为简单通知。
换句话说,我们所说的 Webhook 是在 Web 应用程序中,当某些事情发生时,通过 HTTP POST 调用自动注册的 URL 以通知 Web 应用程序上的用户您请求的数据状态已更改,请查看它。
1.> 首先,我们将创建一个 API,从用户那里获取 KYC 信息,然后通过 RestTemplate 将此信息发送给第三方应用程序以验证用户信息,第三方将 Json Response 作为 KYC 详细信息提交返回给用户.
UserKYCController class
package com.example.com.controller;
@Api
@RestController
@RequestMapping(value = UrlConstant.BASE_URI_V1)
public class UserKYCController {
private Logger logger = LoggerFactory.getLogger(UserKYCController.class);
@Autowired
private UserKYCService userKYCService;
/**
* @param userKYCInput
* @param result
* @return
*/
@RequestMapping(value = UrlConstant.UPLOAD_CONSUMER_KYC_DOCUMENT, method = RequestMethod.POST)
public ResponseEntity<Object> uploadKYCDetails(@Valid @RequestBody UserKYCInput userKYCInput,
BindingResult result) {
if (result.hasErrors()) {
return ResponseHandler.response(HttpStatus.BAD_REQUEST, true, ErrorCollectionUtil.getError(result),
ErrorCode.ERROR, Message("bad.request"),
ResponseCode.ACKNOWLEDGE_OPTIONAL_RESPONSE_OBJECT, ErrorCollectionUtil.getErrorMap(result));
}
ResponseEntity<String> response = userKYCService.sendUserKyc(userKYCInput);
if (response != null) {
return ResponseHandler.response(HttpStatus.OK, false, Message("user.KYC.save.success"),
ErrorCode.OK, ResponseCode.ACKNOWLEDGE, response);
} else {
genericUtil.saveData(userKYCInput);
return ResponseHandler.response(HttpStatus.INTERNAL_SERVER_ERROR, true,
Message("user.KYC.save.failure"), ErrorCode.ERROR,
ResponseCode.ACKNOWLEDGE_OPTIONAL_RESPONSE_OBJECT);
}
}
}
UserKYCServiceImpl class
package com.example.com.service.Userkyc;
@Service
public class UserKYCServiceImpl implements UserKYCService {
public static final Logger logger = LoggerFactory.getLogger(UserKYCServiceImpl.class);
@Autowired
private UserKYCRepository userKYCRepository;
@Value("${user.kyc.restTemplate.url}")
private String kycClientURL;
@Value("${user.kyc.restTemplate.authKey}")
private String kycAuthKey;
@Autowired
private UserService userService;
@Override
public ResponseEntity<String> sendUserKyc(UserKYCInput userKYCDetail) {
RestTemplate restTemplate = new RestTemplate();
String url = kycClientURL;
String base64Creds = kycAuthKey;
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Basic " + base64Creds);
HttpEntity<UserKYCInput> request = new HttpEntity<>(userKYCDetail, headers);
ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, request, String.class);
uploadUserKyc(userKYCDetail, response);
return response;
}
}
2.> 其次,我们将创建另一个 API,并且此 API URL 已在发送用户 KYC 信息的第三方应用程序中注册,当验证成功时,第三方将使用更新的 Json 响应自动调用我们注册的 URL,或者我们可以说用户会通过调用这个注册 URL 被第三方自动通知,所以这个 URL 被称为(Webhook URL)。
UserKYCWebhookController class
package com.example.com.controller;
@Api
@RestController
@RequestMapping(value = UrlConstant.BASE_KYC_WEBHOOK_URI_V1)
public class UserKYCWebhookController {
private static final Logger logger = getLogger(UserKYCWebhookController.class);
@Autowired
private UserKYCService userKYCService;
@Autowired
private WebHookDetailsService webHookDetailsService;
@Autowired
private PasswordEncoderUtil passwordEncoderUtil;
/**
* @param notificationDto
* @param httpRequest
* @throws Exception
*/
@RequestMapping(value = UrlConstant.CONSUMER_KYC_WEBHOOK_NOTIFICATION_REQUEST, method = RequestMethod.POST)
public void getKYCWebhookData(@RequestBody Map<String, Object> notificationDto,HttpServletRequest httpRequest) {
final String authorization = httpRequest.getHeader("Authorization");
logger.debug("authorization {}", authorization);
if (authorization != null && authorization.startsWith("Basic")) {
String base64Credentials = authorization.substring("Basic".length()).trim();
String credentials = new String(Base64.getDecoder().decode(base64Credentials), Charset.forName("UTF-8"));
final String[] values = credentials.split(":", 2);
String userName = values[0].trim();
String password = values[1].trim();
WebHookDetails details = webHookDetailsService.getwebHookDetailsByUserName(userName);
if (Objects.nonNull(details)) {
String tid = notificationDto.get("tid").toString();
String state = notificationDto.get("state").toString();
Map<String, Object> response = new HashMap<>();
response.put("tid", tid);
response.put("state", state);
if (passwordEncoderUtil.matches(password, details.getPassword())) {
userKYCService.saveWebhookUpdatedResponse(response);
} else {
logger.debug("response == {}", false);
}
}
}
}
}
这就是使用 spring web 应用程序实现 webhook 的全部内容。
webhook,简单的来说就是给外部用户提供一个数据推送接口,比如飞书的机器人,企业微信的机器人都是如此。
对于你的应用场景有两种解决办法;
1.你们提供数据变更的接口,让第三方来定时调用;优点:一次开发其他的第三方都可以调用;缺点:数据没有更新也会定时请求,请求量大的时候,需要考虑并发量及性能。而当请求时间间隔设置长后,数据更新通知实时性不高。
2.第三方提供接收数据的接口,你需要维护众多第三方接口,你这边数据变更及时调用所有的第三方接口。优点:及时;缺点:线下沟通成本高,需要第三方都提供数据接口。
webhook没太了解过,但是你需要的消息推送功能我觉得MQTT或许也挺合适的,就是不知道你的具体的应用场景是什么样的,如果技术选型已经确定的话就无视我吧
让外部系统提供一个http接口地址给你,
当你的系统发生变化的时候,就逐个调用这些http接口。
如有帮助,请采纳,十分感谢!
很简单,可以参考一下钉钉的机器人,建一个群,然后添加一个机器人,然后把webhook复制出来之后调用api就可以实现了
SLS告警最佳实践——Webhook通知最佳实践
https://developer.aliyun.com/article/858912