Spring Boot GraphQL Subscription Realtime API

Spring Boot GraphQL Subscription Realtime API

GraphQL Subscription provides a great way of building real-time API. In this tutorial we will build a realtime GraphQL subscription API using Spring Boot.

1. Overview

Spring Boot GraphQL Subscription – GraphQL provides an alternate way of building APIs. Similar to REST, with GraphQL we can query data from server/backend and also update data. This is called Query and Mutation in GraphQL. Checkout the tutorial on Getting Started with GraphQL with Spring Boot in which both Query and Mutation is discussed in detail.

Oftentimes clients want to get pushed updates from the server when data they care about changes. GraphQL Subscription provides this capability of long-lived stream of source events that client can subscribe to.

2. GraphQL Subscription

GraphQL subscriptions are a way to push data from the server to the clients that choose to listen to real time messages from the server. Subscriptions are similar to queries in that they specify a set of fields to be delivered to the client, but instead of immediately returning a single answer, a result is sent every time a particular event happens on the server.

When using Subscription, the client will connect to GraphQL server using Websocket. A persistent websocket connect gets established at the beginning and used across the lifecycle until client wants to consume messages or until server is available. Each time a new message is available, server pushes it on the websocket connection to client.

Designing a realtime API using GraphQL subscription requires careful considerations. Unlike Query and Mutation which are stateless operation types, Subscription is a stateful operation. A stateful connection using WebSocket is established with server. Server should be designed to handle multiple connections and scale along with new connections. Usually to achieve this server can use a messaging service such as RabbitMQ, Redis Pub/Sub or Kafka.

3. Spring Boot GraphQL Subscription API

For this tutorial, we will going to mock the messaging server and send mock data to client through Subscription. Let us start with initializing Spring Boot app.

The next step would be to create Spring Boot app with GraphQL support. Let us scaffold the app with start.spring.io using following options:

  1. Gradle project
  2. Java 11
  3. Spring Boot 2.3.0
  4. Group: net.viralpatel Artifact: spring-boot-graphql-subscription

3.1 Dependencies

Let us add GraphQL Java and other dependencies in Gradle. Open build.gradle file and add following code:

build.gradle

plugins {
    id 'org.springframework.boot' version '2.3.0.RELEASE'
    id 'io.spring.dependency-management' version '1.0.9.RELEASE'
    id 'java'
}
group = 'net.viralpatel'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter'
    implementation 'com.graphql-java-kickstart:graphql-spring-boot-starter:7.0.1'
    implementation 'io.projectreactor:reactor-core'
    runtimeOnly 'com.graphql-java-kickstart:graphiql-spring-boot-starter:7.0.2-SNAPSHOT'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

test {
    useJUnitPlatform()
}

Or if you are using Maven, add following test dependencies.

pom.xml

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>boot:spring-boot-starter</artifactId>
</dependency>
<dependency>
    <groupId>com.graphql-java-kickstart</groupId>
    <artifactId>graphql-spring-boot-starter</artifactId>
    <version>7.0.1</version>
</dependency>
<dependency>
    <groupId>io.projectreactor</groupId>
    <artifactId>reactor-core</artifactId>
</dependency>
<dependency>
    <groupId>com.graphql-java-kickstart</groupId>
    <artifactId>graphiql-spring-boot-starter</artifactId>
    <version>7.0.2</version>
    <scope>runtime</scope>
</dependency>

3.2 GraphQL Schema SDL

The GraphQL schema can be written using GraphQL SDL (Schema Definition Language). Following is our app’s GraphQL schema.

Schema definition file is under src/resources directory. GraphQL Spring Boot starter will read this and configure it using graphql-java-tools.

src/resources/schema.graphqls

type Query {
    stockDetail(symbol: String): StockDetail
}

type Subscription {
    stockPrice(symbol: String): StockPrice
}

type StockDetail {
    symbol: String,
    name: String,
    marketCap: String
}

type StockPrice {
    symbol: String
    price: String
    timestamp: String
}

The schema consist of GraphQL Query and Subscription default operation types. It also contains user defined types StockDetail and StockPrice.

The Query stockDetail returns the type StockDetail and is used as GET API to get the stock detail once when called. The Subscription method stockPrice returns the type StockPrice. Since it is Subscription method, instead of returning the result once it subscribe to the method and listen for any changes from server. Server will push changes in realtime whenever there is new data available.

3.3 Query Resolver

The Spring Boot Graphql starter expects an instance of GraphQLQueryResolver in classpath when the app boots.

QueryResolver.java

package net.viralpatel.springbootgraphqlsubscription;

import graphql.kickstart.tools.GraphQLQueryResolver;
import net.viralpatel.springbootgraphqlsubscription.model.StockDetail;
import org.springframework.stereotype.Component;

@Component
public class QueryResolver implements GraphQLQueryResolver {

    public StockDetail stockDetail(String symbol) {

       return new StockDetail(symbol, "name", 2000l);
    }
}

The custom QueryResolver class defines method stockDetail which matches to the GraphQL SDL we defined above. This method will be invoked whenever the client calls the Query method stockDetail.

The response is just hardcoded value of stock symbol, name and price. Instead of hardcoding, these values can come from database or any backend API.

3.3 Subscription Resolver

Similar to QueryResolver, the custom SubscriptionResolver class is required on classpath when using subscription type in GraphQL SDL.

SubscriptionResolver.java

package net.viralpatel.springbootgraphqlsubscription;

import graphql.kickstart.tools.GraphQLSubscriptionResolver;
import net.viralpatel.springbootgraphqlsubscription.model.StockPrice;
import org.reactivestreams.Publisher;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Flux;

import java.time.Duration;
import java.time.LocalDateTime;
import java.util.Random;

@Component
public class SubscriptionResolver implements GraphQLSubscriptionResolver {

    public Publisher<StockPrice> stockPrice(String symbol) {

        Random random = new Random();
        return Flux.interval(Duration.ofSeconds(1))
                .map(num -> new StockPrice(symbol, random.nextDouble(), LocalDateTime.now()));
    }
}

The custom SubscriptionResolver class contains stockPrice method which matches to the GraphQL SDL we defined earlier. This method will be invoked whenever client subscribe for this method. The client would establish a websoket connection with server and the stockPrice() method will return a project reactor’s Publisher instance. The Publisher instace does not return the result immediately rather it will send the result whenever server pushes it. This is the same way Spring Boot Webflux pushes the result non-blocking way.

For simplicity, we have hardcoded the result. The stockPrice() method would return a random value every second using Flux.interval method. Instead of hardcoding these results can also come from a Kafka topic or RabbitMQ queue.

StockDetail.java

package net.viralpatel.springbootgraphqlsubscription.model;

public class StockDetail {
    private String symbol;
    private String name;
    private long marketCap;

    public StockDetail(String symbol, String name, long marketCap) {
        this.name = name;
        this.symbol = symbol;
        this.marketCap = marketCap;
    }

    // getter and setters
}

StockPrice.java

package net.viralpatel.springbootgraphqlsubscription.model;

import java.time.LocalDateTime;

public class StockPrice {
    private String symbol;
    private double price;
    private LocalDateTime timestamp;

    public StockPrice(String symbol, double price, LocalDateTime timestamp) {
        this.price = price;
        this.symbol = symbol;
        this.timestamp = timestamp;
    }

    // getter and setters
}

The above are just some plain old Java objects to carry the data from server to client.

4. Build and Execute

Start the Spring Boot application by running SpringBootGraphqlSubscriptionApplication class or by running gradle:

./gradlew bootRun

Once the Spring Boot app is started on default port 8080, open http://localhost:8080/graphiql

Try running following GraphQL subscription method and see the output.

subscription {
  stockPrice(symbol: "GOOG") {
    symbol
    price
    timestamp
  }
}

At first we will see following output in Graphiql editor.

Your subscription data will appear here after server publication!

And after a few seconds we should start getting result back from server.

{
  "stockPrice": {
    "symbol": "GOOG",
    "price": "0.7199789993583869",
    "timestamp": "2020-05-24T19:41:51.780299"
  }
}
Spring Boot GraphQL Subscription GraphiQL Editor

5. Source Code – Spring Boot GraphQL Subscription Example

Source code for the Spring Boot GraphQL Subscription API.

Github – spring-boot-graphql-subscription



via ViralPatel.net https://ift.tt/36qUpKQ

[Tip] Disable Link Doctor Suggesting Similar Websites for Incorrect URLs in Microsoft Edge

https://ift.tt/eA8V8J In newer versions of Microsoft Edge web browser, if you mistype a URL (typing mistakes in URLs), the browser suggests similar...

Read the full article at AskVG.com

via AskVG https://ift.tt/3eiScUq

[Tip] Disable Typing Suggestions from Favorites and History in Microsoft Edge Address bar

https://ift.tt/eA8V8J When you start typing in Microsoft Edge address bar (or Omnibox), the browser starts showing typing suggestions (in a drop-down list)...

Read the full article at AskVG.com

via AskVG https://ift.tt/2Zv2uNm

[Tip] New Way to Install and Use Google Chrome Themes in Microsoft Edge

https://ift.tt/eA8V8J We know that Microsoft Edge web browser supports Google Chrome extensions/add-ons and we can install and use Chrome extensions in Microsoft...

Read the full article at AskVG.com

via AskVG https://ift.tt/2XoRpKR

[Tip] Enable Dark Mode in WhatsApp Web on Your Computer

https://ift.tt/eA8V8J Most of us use the popular social networking app WhatsApp in our smartphones. WhatsApp also allows users to use their mobile...

Read the full article at AskVG.com

via AskVG https://ift.tt/3cSXmX5

[Tip] Always Show Full URLs (Including HTTPS and WWW) in Google Chrome Address bar

https://ift.tt/eA8V8J This article will help you in restoring HTTPS and WWW terms for website URLs in Google Chrome address bar. You can...

Read the full article at AskVG.com

via AskVG https://ift.tt/2ZjyVOF

Simple Trick To Take Complete Control Over Scrolling in Google Photos

Google Photos does an amazing job of creating a timeline of your photos and videos. However, if you have too many photos over a long period (say 5+ years), then scrolling through all of them to find photos from specific time periods can be a little tedious. You can either go the slow route by swiping up/down, or go fast by jumping from year to year using the scroll bar. There seems to be no in-between the fast and slow scrolling (or is it?).

Well, today I am going to share a quick tip to easily scroll in Google Photos at whatever speed you are comfortable with.

Scroll easily in Google Photos

The trick is actually hidden in the scroll bar at the right side of the screen which shows up when you swipe up. Usually, when you grab the scroll bar and move it down, it moves at extreme speed to the point you can’t even see the scrolling photos. Well, you can easily slow down the speed by grabbing the scroll bar and moving your finger to the left of the screen and then scroll.

The trick is that the scroll bar speed is slowed down the more you move your finger to the left of the screen before scrolling. For example, grabbing and moving the finger to the middle of the screen will slow it down enough to easily see photos over a month’s period. Similarly, if you move it to the left end of the screen, then the scroll speed will be slow enough to view photos per day.

Easily scroll in Google Photos

Now how is this helpful you are wondering? Well, think about this scenario: You need to find 4 years old photos taken in the middle of March and some in September that you don’t know the exact date of. You can just grab the scroll bar to quickly move 4 years back and then move your finger to the middle of the screen to slowly scroll through September’s photos. And then again you can move your finger back to the right-side to speedup scrolling to move to March and then move the finger to the left-end to see photos taken in the middle of March.

I also believe that this is much faster and convenient than separately searching for the photos using the search bar.

Ending words

Although quite a necessary feature, the instructions to control scrolling speed isn’t provided by Google Photos (not even a hint). I am sure you will find this little trick very useful for scrolling through thousands of photos.

I should mention though that I had a bit of trouble controlling the scroll bar while needing to do multiple swipes (you don’t have an endless screen). While moving the finger from right to left, the high sensitivity usually messed up my current scroll position. Of course, this could be just me and my shaky hands.

The post Simple Trick To Take Complete Control Over Scrolling in Google Photos appeared first on Gtricks.



via Gtricks https://ift.tt/2AN5zOr

[Changelog] What’s New in Microsoft Edge 130 and Later Versions

UPDATE: Addition of Microsoft Edge 132.0 version. In this exclusive changelog article, we are providing information about all versions of Mi...