简体   繁体   English

如何为 REST API 实现观察者模式?

[英]How to implement the observer pattern for REST API's?

I'm looking to create a REST API to which clients subscribe to certain data.我正在寻找创建一个 REST API,客户端订阅某些数据。 When the data changes (due to some external event) I want to notify the clients (observers) with the new data.当数据更改时(由于某些外部事件),我想用新数据通知客户端(观察者)。

I want to use Spring for the REST API's, I have no clue how to register and notify the observers though.我想将 Spring 用于 REST API,但我不知道如何注册和通知观察者。

Some guidance and or good practises would be very helpful.一些指导和/或良好做法将非常有帮助。

Thank you谢谢

You can use Spring 5 with WebFlux.您可以将 Spring 5 与 WebFlux 一起使用。 It's a combination of an Iterator and the Observer pattern.它是迭代器和观察者模式的组合。 The client always gets a new Object, whenever there is one on the server.每当服务器上有一个新对象时,客户端总是会得到一个新对象。 You can start learning more on that on the Spring documentation pages or on eg New in Spring 5: Functional Web Framework您可以在 Spring 文档页面或例如Spring 5 中的新功能:功能性 Web 框架中开始学习更多相关内容

I hesitate to put my answer up because the other is much better, but since I've done some code.我犹豫是否提出我的答案,因为另一个要好得多,但因为我已经完成了一些代码。

In spring boot you can register call back urls, an example controller is:在 spring boot 中,您可以注册回调 url,一个示例控制器是:

@RestController
public class Controller {

    private List<Listener> listeners = new ArrayList<>();

    @RequestMapping(value = "/register/{name}", method = RequestMethod.POST)
    public ResponseEntity<Void> register(@PathVariable("name") String name, @RequestParam("callbackurl") String callBackUrl) throws Exception {
        System.out.println("register, name=" + name + ", callBackUrl=" + callBackUrl);
        Listener listener = new Listener(name, URLDecoder.decode(callBackUrl, "UTF-8"));
        listeners.add(listener);
        System.out.println(listener);
        return new ResponseEntity<>(HttpStatus.OK);
    }

    @RequestMapping(value = "/callback/*", method = RequestMethod.POST)
    public ResponseEntity callBack(@RequestBody String message) {
        System.out.println("call back with message=" + message);
        return new ResponseEntity(HttpStatus.OK);
    }

    @Scheduled(fixedRate = 10000)
    public void notifyListeners() {
        System.out.println("notifying listeners");
        for (Listener listener : listeners) {
            System.out.println("listener " + listener);
            CloseableHttpClient client = HttpClients.createDefault();
            HttpPost httpPost = new HttpPost(listener.getCallBackUrl());
            try {
                httpPost.setEntity(new StringEntity("hello listener " + listener));
                CloseableHttpResponse response = client.execute(httpPost);
                client.close();
            } catch (Exception e) {
            }
        }
    }
}

Can be tested like so, register 2 call backs, the URL http://127.0.0.1:8080/callback/app1 is encoded so it can be a paramter.可以这样测试,注册 2 个回调,URL http://127.0.0.1:8080/callback/app1被编码所以它可以是一个参数。

curl -X POST http://127.0.0.1:8080/register/listener1?callbackurl=http%3A%2F%2F127.0.0.1%3A8080%2Fcallback%2Fapp1
curl -X POST http://127.0.0.1:8080/register/listener1?callbackurl=http%3A%2F%2F127.0.0.1%3A8080%2Fcallback%2Fapp2

In my case for simplicity the client and server are the same application, but they could be different.在我的例子中,为简单起见,客户端和服务器是同一个应用程序,但它们可能不同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM