<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Héctor Valls</title>
    <description>The latest articles on DEV Community by Héctor Valls (@hhccvvmm).</description>
    <link>https://dev.to/hhccvvmm</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F14753%2Fd79d2e83-54b2-40f6-a314-4ff3c239b1c1.png</url>
      <title>DEV Community: Héctor Valls</title>
      <link>https://dev.to/hhccvvmm</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/hhccvvmm"/>
    <language>en</language>
    <item>
      <title>Push vs Polling vs Long Polling</title>
      <dc:creator>Héctor Valls</dc:creator>
      <pubDate>Tue, 03 Aug 2021 08:43:44 +0000</pubDate>
      <link>https://dev.to/hhccvvmm/push-vs-polling-vs-long-polling-3ogb</link>
      <guid>https://dev.to/hhccvvmm/push-vs-polling-vs-long-polling-3ogb</guid>
      <description>&lt;p&gt;Sometimes, we need to build "event-based" applications like a chat, an app showing the current price of a crypto currency or an event-driven microservices architecture, for example. In these cases, we have to decide what communication model fits better in terms of performance and scalability for an specific use case. Basically, we have three models: push, polling and long polling. Let's see the conceptual differences between them.&lt;/p&gt;

&lt;h3&gt;Push&lt;/h3&gt;

&lt;p&gt;In this model, client opens a connection to the server and waits for messages. The connection is kept open and server pushes messages synchronously to the client when it receives them.&lt;/p&gt;

&lt;p&gt;This model is the most "real-time" one of the three: messages goes to the client as soon as they are received by the server. And, precisely because of that, it is not the most scalable one. Server does not know if client is ready to consume new messages and may become busy, slowing down the server.&lt;/p&gt;

&lt;p&gt;Pushing model is appropriate when you have limited clients/consumers and messages. For example, a chat application like Whatsapp where there are few clients per group or "channel" (in fact, WhatsApp uses this model). RabbitMQ and Redis Pub/Sub are some technologies using push model.&lt;/p&gt;

&lt;h3&gt;Polling&lt;/h3&gt;

&lt;p&gt;Unlike pushing, polling is a request/response model. Client makes a request to the server and gets a response from it immediately with a new message or without any.&lt;br&gt;
This model is a waste of bandwith when there are no new messages and responses contain no data. Also, open and close connections is expensive. Although this model does not scale well, it is the easiest one to implement and could be useful is some scenarios where scalability and performance is not a concern at all.&lt;/p&gt;

&lt;h4&gt;Long polling&lt;/h4&gt;

&lt;p&gt;This one is a combination of the two previous models: client makes a request to the server, but this is kept open until a "useful" response is returned. What do I mean with "useful" response? Well, problem with polling are empty responses, wasting bandwidth and server resources. With long polling, client tells the server "Hey, reply to me when there is some new message, I will wait for that". This way, server knows that specific client is ready to receive messages and can send them to it. &lt;/p&gt;

&lt;p&gt;Two interesting things here. Once response is returned, client/server connection is closed and client is responsible of make another request to the server when it's ready to handle new messages. Besides, client can provide extra information to the server to achieve a better performance: for instance, it could tells the server "Hey, reply to me when there are three new messages or when the pending messages are 25Kb or more". This way, message handling is optimised and client/server communication is more efficient. Internally, this model could be implemented as a server-side local-polling model.&lt;/p&gt;

&lt;p&gt;Kafka is an example of technology implementing long polling model, and that's the reason why it is more scalable compared with RabbitMQ when there is a massive amount of messages and clients. Also, it's worth to mention that Server Sent Events (SSE) is a protocol that implements long polling model, with the difference that it does not close the connection after a message is sent to the client, but it is kept open. &lt;/p&gt;

&lt;p&gt;As you saw, I didn't mention any protocol or specific technology to implement these three patterns because, actually, they are protocol agnostic. &lt;/p&gt;

&lt;p&gt;I hope you enjoyed the post!&lt;/p&gt;

</description>
      <category>backend</category>
      <category>push</category>
      <category>polling</category>
      <category>events</category>
    </item>
    <item>
      <title>API documentation in event driven applications</title>
      <dc:creator>Héctor Valls</dc:creator>
      <pubDate>Sat, 02 May 2020 17:53:15 +0000</pubDate>
      <link>https://dev.to/hhccvvmm/api-documentation-in-event-driven-applications-4ehb</link>
      <guid>https://dev.to/hhccvvmm/api-documentation-in-event-driven-applications-4ehb</guid>
      <description>&lt;p&gt;We live in the era of the distributed systems. Airlines and hotels communicate each other to offer us a better experience in our travels; shops work with shipping companies so we have our new products in our homes in a matter of hours. All of these integrations across services are done using APIs. Those APIs must be well documented so the consumers can integrate with them easily. This is not only a technical matter but also a business related one.&lt;/p&gt;

&lt;p&gt;Currently, the most used API protocols are &lt;a href="https://en.wikipedia.org/wiki/Representational_state_transfer"&gt;REST&lt;/a&gt; and &lt;a href="https://graphql.org/"&gt;GraphQL&lt;/a&gt;. You can document your REST API using &lt;a href="https://swagger.io/specification/"&gt;OpenAPI&lt;/a&gt; initiative. In the case of GraphQL, you can use tools like GraphiQL, which makes supported operations visible through &lt;a href="https://graphql.org/learn/introspection/"&gt;introspection query&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Both protocols are essentially synchronous: you make a request against the API and wait for a response. But what happens when you are to design an asynchronous event oriented API? OpenAPI has been designed to document request/response APIs and GraphQL has its own specific mechanism so they are not applicable in this case. &lt;a href="https://www.asyncapi.com/"&gt;AsyncAPI&lt;/a&gt; to the rescue.&lt;/p&gt;




&lt;p&gt;Let's imagine you work on a book shopping website called &lt;em&gt;SuperFunnyBooks&lt;/em&gt;. Your team is responsible of the &lt;code&gt;Catalog Service&lt;/code&gt;. Book publishers can register new books to the platform through your service. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;SuperFunnyBooks&lt;/em&gt; product team needs a new feature to be added: when a new book is registered on the platform, it has to be recommended to users interested in that genre. To do this, a brand new service, &lt;code&gt;Recommendation Service&lt;/code&gt;, is created and a new team is assigned to. &lt;/p&gt;

&lt;p&gt;The new service needs to know when a new book is registered in the platform, so &lt;code&gt;Catalog Service&lt;/code&gt; will publish a &lt;code&gt;BookRegistered&lt;/code&gt; event to a message queue every time this happens. This event will contain information about the new book. But, where is located that message queue? and what does exactly "information about the new book" mean? It sounds a little bit abstract and vague. &lt;code&gt;Recommendation Service&lt;/code&gt; team needs to know every single field is going to be included in the event's payload, as well as how to connect to the message queue to start listening for new events. In other words, they need the API documentation. &lt;/p&gt;

&lt;p&gt;This is how this event oriented API would look like with AsyncAPI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;asyncapi&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;2.0.0&lt;/span&gt;
&lt;span class="na"&gt;info&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Catalog Service&lt;/span&gt;
  &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;1.0.0'&lt;/span&gt;

&lt;span class="na"&gt;servers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;production&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;catalog.superfunnybooks.com:9092&lt;/span&gt;
    &lt;span class="na"&gt;protocol&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;kafka&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Production Kafka&lt;/span&gt; 

&lt;span class="na"&gt;channels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="s"&gt;book/registered&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Book Registered Topic&lt;/span&gt;
    &lt;span class="na"&gt;subscribe&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;summary&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Receive information about new book registered in catalog&lt;/span&gt;
      &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;BookRegistered&lt;/span&gt;
        &lt;span class="na"&gt;contentType&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;application/json&lt;/span&gt;
        &lt;span class="na"&gt;payload&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;object&lt;/span&gt;
          &lt;span class="na"&gt;properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;bookId&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;string&lt;/span&gt;
            &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;string&lt;/span&gt;
            &lt;span class="na"&gt;author&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;string&lt;/span&gt;
            &lt;span class="na"&gt;genre&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;string&lt;/span&gt;
            &lt;span class="na"&gt;publisherId&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;string&lt;/span&gt;
            &lt;span class="na"&gt;registeredAt&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;string&lt;/span&gt;
              &lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;datetime&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The first part contains API metadata information. Then, server information is declared; in this case, there is a Kafka server running on &lt;code&gt;catalog.superfunnybooks.com&lt;/code&gt; at port &lt;code&gt;9092&lt;/code&gt;. &lt;code&gt;channels&lt;/code&gt; object groups all the operations that the API supports. This one allows consumers to subscribe to &lt;code&gt;book/registered&lt;/code&gt; channel to be notified when a new book is registered. Also, the concrete event's payload schema is defined. &lt;/p&gt;

&lt;p&gt;With this document, API is properly defined and it provides a contract between &lt;code&gt;Catalog Service&lt;/code&gt; and its consumers. Now, &lt;code&gt;Recommendation Service&lt;/code&gt; knows where the message queue is located in the network and how exactly an event's payload looks like.&lt;/p&gt;




&lt;p&gt;To sum up, having a nice API documentation improves communication between teams in a company as well as between external stakeholders. Also, using a machine-friendly format (like YAML) in an API documentation enables it to be integrated in the development lifecycle and the possibility of taking advantage of techniques like server stubbing or automatic testing.&lt;/p&gt;

&lt;p&gt;This has been a simple example of how to use AsyncAPI specification to document event oriented APIs. &lt;a href="https://www.asyncapi.com/docs/specifications/2.0.0/#specification"&gt;AsyncAPI spec&lt;/a&gt; provides a lot of options that allow to define clearly many aspects of an API. It is worth keeping it in mind.&lt;/p&gt;

&lt;p&gt;I hope you enjoyed this post!&lt;/p&gt;

</description>
      <category>api</category>
      <category>documentation</category>
      <category>asyncapi</category>
      <category>event</category>
    </item>
    <item>
      <title>GraphQL for server-side resource aggregation</title>
      <dc:creator>Héctor Valls</dc:creator>
      <pubDate>Thu, 12 Mar 2020 19:44:40 +0000</pubDate>
      <link>https://dev.to/hhccvvmm/graphql-for-server-side-resource-aggregation-4o9h</link>
      <guid>https://dev.to/hhccvvmm/graphql-for-server-side-resource-aggregation-4o9h</guid>
      <description>&lt;p&gt;When implementing service oriented and microservices architectures, sooner or later, the aggregation of data coming from different services becomes a problem to face. In this post, we will see how GraphQL can help with this.&lt;/p&gt;

&lt;p&gt;(A basic knowledge of GraphQL is required. You can learn GraphQL basics on the &lt;a href="https://graphql.org/learn/"&gt;official website&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;We are developing a property rental API, and the consumer needs an endpoint to fetch information about a property and its landlord. An example response would look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GET /properties/1234

{
    id: 1234,
    address: "10 Downing Street",
    area: 90,
    landlord: {
        id: 882,
        name: "John Doe"
        email: "john.doe@mail.com"
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We can see two &lt;a href="https://martinfowler.com/bliki/DDD_Aggregate.html"&gt;aggregates&lt;/a&gt; involved in this piece of information: &lt;em&gt;Property&lt;/em&gt; and &lt;em&gt;Landlord&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;In a monolithic application, we would write a query, with some SQL &lt;code&gt;JOIN&lt;/code&gt; maybe, to fetch the data from a database, and marshall it to the above &lt;em&gt;JSON&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;However, let's assume in our rental organization we have a microservices architecture; we have a &lt;em&gt;Property Microservice&lt;/em&gt; and &lt;em&gt;Landlord Microservice&lt;/em&gt;, &lt;a href="https://microservices.io/patterns/data/database-per-service.html"&gt;with a database for each one&lt;/a&gt;. For that reason, we can't just &lt;code&gt;JOIN&lt;/code&gt; two database tables; integration between services is made across the network and not through database sharing.&lt;/p&gt;

&lt;p&gt;We need an &lt;a href="https://hvalls.dev/posts/microservice-pattern-api-gateway"&gt;API Gateway&lt;/a&gt; or &lt;a href="https://samnewman.io/patterns/architectural/bff/"&gt;BFF&lt;/a&gt; to aggregate data from both services and serve it to the API consumer.&lt;/p&gt;

&lt;p&gt;We could perform aggregation "by hand":&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="c1"&gt;//This code belongs to API Gateway / BFF&lt;/span&gt;
&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;getProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;JsonObject&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;property&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;propertyService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;landlord&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;landlordService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;property&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;landlordId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;buildJson&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;property&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;landlord&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Note that &lt;code&gt;property&lt;/code&gt; object, fetched from &lt;code&gt;propertyService::getById&lt;/code&gt;, does not contain information about its &lt;code&gt;landlord&lt;/code&gt;, but only its identifier; &lt;code&gt;landlordId&lt;/code&gt;. We use that field to fetch the whole landlord info, through &lt;code&gt;landlordService&lt;/code&gt;, and construct the full response &lt;code&gt;JsonObject&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;When implementing this approach, due to its stream-based nature, reactive programming tools like ReactiveX are quite useful.&lt;/p&gt;

&lt;p&gt;An alternative to this, is letting GraphQL engine do the job.&lt;/p&gt;

&lt;h3&gt;
  
  
  Resource aggregation using GraphQL
&lt;/h3&gt;

&lt;p&gt;First, we are going to define the GraphQL schema:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Query&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;getProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;!):&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Property&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Property&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;address&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;area&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Int&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;landlord&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Landlord&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Landlord&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now, we have to define a data fetcher for &lt;code&gt;getProperty&lt;/code&gt; operation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;getPropertyDataFetcher&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;DataFetcher&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;DataFetcher&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;propertyId&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getArgument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
     &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;propertyService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;propertyId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;So far, we have the information about the property. Now, we need to implement the data fetcher for its landlord:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;getLandlordDataFetcher&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;DataFetcher&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;DataFetcher&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;property&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getSource&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Property&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;()&lt;/span&gt;
     &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;landlordId&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;property&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;landlordId&lt;/span&gt;
     &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;landlordService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getLandlord&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;landlordId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;With the schema and the fetchers, we are ready to build our &lt;code&gt;GraphQL&lt;/code&gt; instance and make the query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;graphQL&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;buildGraphQLFromSchemaAndFetchers&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nf"&gt;executeQuery&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;graphQL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"""{ query:
  getProperty(id: 1234) {
    id
    address
    area
    landlord {
      id
      name
      email
    }
  }
}"""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;With this approach, we delegate the logic of the data composition to GraphQL library implementation, this way being less error-prone than doing it manually.&lt;/p&gt;

&lt;p&gt;It looks like a declarative way; you tell it how to fetch properties, and how to fetch landlords. Then, just ask for the data you need and data aggregation is managed by GraphQL.&lt;/p&gt;




&lt;p&gt;Sometimes, we tend to think of GraphQL just as a type of HTTP API; an alternative to REST.&lt;br&gt;
This is true, but using GraphQL does not mean starting a GraphQL server. You don't need to expose an API of this type at all, depending on the use case you are trying to solve.&lt;/p&gt;

&lt;p&gt;In this example, I have shown how to use GraphQL as a query engine and data aggregator, but I haven't mentioned anything about GraphQL servers.&lt;/p&gt;

&lt;p&gt;Let's consider this code, that could be written using some modern REST tool:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nd"&gt;@GET&lt;/span&gt;
&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;getProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@PathParam&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Property&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;property&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;executeQuery&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;graphQL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"""{ query:
    getProperty(id: $id) {
      id
      address
      area
      landlord {
        id
        name
        email
      }
    }
  }"""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;property&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This is a REST API resource, but, under-the-hood, a GraphQL engine is responsible for aggregation of data from several sources. &lt;strong&gt;There is no need to run any GraphQL server&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;There are many reasons you may not want to expose a pure GraphQL API. e.g. hard integration with frontend or other services, maintain compatibility, lack of GraphQL knowledge amongst the developers, or even organizational convention. Anyway, you can take advantage of GraphQL power and use it as a query engine, like we have just seen above.&lt;/p&gt;

&lt;p&gt;I hope you enjoyed the article!&lt;/p&gt;

</description>
      <category>graphql</category>
      <category>microservices</category>
      <category>apigateway</category>
      <category>bff</category>
    </item>
  </channel>
</rss>
