Подписки Netflix DGS
Я слежу за документацией по подпискам DGS, и я не получаю никаких ошибок, но и не получаю никаких данных.
Настройка очень проста. В файле schema.graphqls я определил подписку:
type Subscription {
ratings: Rating
}
type Rating {
stars: Int
}
А код Java выглядит следующим образом:
@DgsComponent
public class SubscriptionDataFetcher {
@DgsData(parentType = "Subscription", field = "ratings")
public Publisher<Rating> ratings() {
return Flux.interval(Duration.ofSeconds(1)).map(t -> new Rating(4));
}
}
Если я теперь подключаю веб-сокет к своему бэкэнду, он подключается нормально, но не получает никаких данных, как ожидалось (неважно, как я это делаю, также пытался использовать JavaScript, также подключается отлично, но не получает никаких данных).
Например, используя curl для подключения (но при использовании JavaScript результат тот же, подключается, но нет данных):
curl -o - --http1.1 \
--include \
--no-buffer \
--header "Connection: Upgrade" \
--header "Upgrade: websocket" \
--header "Host: localhost:8443" \
--header "Origin: https://localhost:8443" \
--header "Sec-WebSocket-Key: SGVsbG8sIHdvcmxkIQ==" \
--header "Sec-WebSocket-Version: 13" \
https://localhost:8443/subscriptions\?query\=ewoicXVlcnkiOiAic3Vic2NyaXB0aW9uIHsgIHN0b2NrcyB7bmFtZX0gfSIKfQ==
Я также пробовал подключиться через интерфейс Graphiql, но это дает ошибку:
subscription {
ratings {
stars
}
}
Сообщение об ошибке:
{
"message": "response is not defined",
"stack": "ReferenceError: response is not defined\n at https://localhost:8443/graphiql:46:35\n at async Object.onRun (https://unpkg.com/graphiql/graphiql.min.js:1:540500)"
}
Еще одна вещь, которая мне непонятна из примеров по ссылке, - это как на самом деле управлять подписками. Так, например, скажем, я хочу опубликовать уведомление, если происходит мутация. Любые указания на то, как это можно сделать с помощью инфраструктуры Netflix DGS, также будут очень благодарны.
1 ответ
К сожалению, интерфейс graphiql, поставляемый с DGS, похоже, не обрабатывает подписки должным образом - если вы добавите playground-spring-boot-starter
к вашему проекту, более совершенный инструмент будет доступен по адресу
/playground
, который полностью поддерживает подписки. Если вы попробуете свою подписку там, она должна работать (при условии, что вы уже добавилиgraphql-dgs-subscriptions-websockets-autoconfigure
согласно документации).
Что касается вашего второго вопроса о том, как опубликовать уведомление, если происходит мутация - это, к сожалению, отсутствует в документации, но есть пример в репозитории примеров .
Я немного урезал пример здесь. Если вы хотите поддержать подписку и мутацию следующим образом:
@DgsSubscription
public Publisher<Review> reviewAdded() {
return reviewsService.getReviewsPublisher();
}
@DgsMutation
public Review addReview(@InputArgument SubmittedReview review) {
return reviewsService.saveReview(review);
}
Внутри вашего сервиса вы должны создать Flux (для возврата подписчикам) и сохранить ссылку на его эмиттер, чтобы вы могли вызывать его при каждом изменении.
@Service
public class ReviewsService {
private FluxSink<Review> reviewsStream;
private ConnectableFlux<Review> reviewsPublisher;
@PostConstruct
public void init() {
Flux<Review> publisher = Flux.create(emitter -> {
reviewsStream = emitter;
});
reviewsPublisher = publisher.publish();
reviewsPublisher.connect();
}
public Review saveReview(SubmittedReview reviewInput) {
Review review = Review.newBuilder()
.username(reviewInput.getUsername())
.starScore(reviewInput.getStarScore())
.submittedDate(OffsetDateTime.now()).build();
// Save to the database, etc.
reviewsStream.next(review); // publishes the review to subscribers
return review;
}
public Publisher<Review> getReviewsPublisher() {
return reviewsPublisher;
}
}