<?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: Dozer</title>
    <description>The latest articles on DEV Community by Dozer (@getdozer).</description>
    <link>https://dev.to/getdozer</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%2Forganization%2Fprofile_image%2F6864%2F93cbe74a-92e6-4415-89a0-a527e0c43038.png</url>
      <title>DEV Community: Dozer</title>
      <link>https://dev.to/getdozer</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/getdozer"/>
    <language>en</language>
    <item>
      <title>Creating a Low-Latency Cache with Dozer and PostgreSQL</title>
      <dc:creator>Abhishek Mishra</dc:creator>
      <pubDate>Tue, 30 May 2023 05:56:29 +0000</pubDate>
      <link>https://dev.to/getdozer/creating-a-low-latency-cache-with-dozer-and-postgresql-i18</link>
      <guid>https://dev.to/getdozer/creating-a-low-latency-cache-with-dozer-and-postgresql-i18</guid>
      <description>&lt;p&gt;In the realm of software development and data management, the efficiency of data retrieval plays a crucial role in the overall performance of an application. One effective way to enhance this efficiency is by implementing a cache. A cache is a high-speed data storage layer that stores a subset of data, typically transient in nature so that future requests for that data are served up faster than is possible by accessing the data’s primary storage location.&lt;/p&gt;

&lt;p&gt;This blog post explores how to enhance these aspects by implementing a low-latency cache using &lt;a href="https://github.com/getdozer/dozer" rel="noopener noreferrer"&gt;Dozer&lt;/a&gt; and &lt;a href="https://www.postgresql.org/" rel="noopener noreferrer"&gt;PostgreSQL&lt;/a&gt;. We delve into the importance of caching in data management, the limitations of not having a cache, and the unique advantages of using Dozer as a cache layer. We also provide a guide on how to use Dozer for real-time data ingestion from PostgreSQL. This post is a must-read for developers seeking to improve their application's performance and responsiveness, and for those looking to simplify their data infrastructure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Do We Need a Cache on Top of PostgreSQL?
&lt;/h2&gt;

&lt;p&gt;PostgreSQL is a powerful, open-source object-relational database system. It is highly extensible and enables high performance on complex queries and heavy loads. However, like any other database, it has its limitations.&lt;/p&gt;

&lt;p&gt;When a database grows in size and complexity, the time taken to retrieve data can increase significantly. This is especially true for complex queries that involve multiple joins and aggregations. In such scenarios, every millisecond counts, and the latency can add up quickly, leading to a slow and unresponsive application.&lt;/p&gt;

&lt;p&gt;This is where a cache comes into play. A cache is a high-speed data storage layer that stores a subset of data so that future requests for that data are served up faster than is possible by accessing the data’s primary storage location. By storing frequently accessed data in a cache, we can significantly reduce the time taken to access this data.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's the Problem with Not Having a Cache?
&lt;/h2&gt;

&lt;p&gt;Without a cache, every time a client requests data, the application has to query the database. This can be a time-consuming operation, especially if the database is large or the query is complex. This can lead to increased latency and a poor user experience.&lt;/p&gt;

&lt;p&gt;Moreover, without a cache, the database can become a bottleneck, especially under heavy load. Every read and write operation involves a significant amount of work, and as the number of operations increases, the time taken to complete these operations also increases. This can lead to increased CPU and memory usage, and in extreme cases, it can even lead to database crashes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Not PostgreSQL Read Replica?
&lt;/h2&gt;

&lt;p&gt;While a PostgreSQL read replica can certainly help offload some of the read operations from your primary database, it's not without its limitations. The process of querying a read replica still involves a network round trip and the overhead of a database query. These factors can contribute to latency, especially when dealing with large volumes of data or complex queries. A cache like the one provided by Dozer, on the other hand, can serve data much faster than a read replica.&lt;/p&gt;

&lt;p&gt;In terms of using a read replica instead of a cache layer like Dozer, it depends on your specific use case and requirements. A read replica can help improve read performance by distributing read traffic across multiple instances, but it may not provide the same level of performance improvement as a cache layer like Dozer.&lt;/p&gt;

&lt;p&gt;Moreover, Dozer doesn't make a distinction between types of data sources. Developers can get a seamless experience building products with application databases such as Postgres and MySQL, data warehouses such as SnowFlake and cloud storage such as S3 and Deltalake. Dozer can also consume real-time events and Ethereum data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Dozer?
&lt;/h2&gt;

&lt;p&gt;In the context of database management, most OLTP workloads involve random disk I/O usage. Given that disks, including SSDs, are slower in performance than RAM, database systems use caching to increase performance. Caching is all about storing data in memory (RAM) for faster access at a later point in time.&lt;/p&gt;

&lt;p&gt;One approach to database caching involves replicating data using Change Data Capture (CDC) to an alternative database optimized for your queries. This method is increasingly being adopted for operations that require extensive data reading. However, it comes with its own set of challenges such as ensuring real-time data, managing indexing, guaranteeing availability, handling schema changes, and considering costs. Dozer addresses these pain points by providing an end-to-end system that takes care of the complexity of caching logic, allowing developers to focus on building their applications.&lt;/p&gt;

&lt;p&gt;Dozer, an open-source data API backend, provides a solution to this. It connects to any of your data sources, transforms and stores the data in an embedded cache powered by LMDB, automatically creates secondary indexes, and instantly generates low-latency REST and gRPC APIs. Dozer is implemented fully in Rust for fast processing of data and is less resource intensive.&lt;/p&gt;

&lt;p&gt;Without a cache layer, data retrieval would rely solely on the performance of the PostgreSQL database and its internal caching mechanisms. This can result in slower response times and increased load on the database server. By using a cache layer like Dozer, you can improve the performance of data retrieval and reduce the load on the database server.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Use Dozer as a Cache
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Architecture Diagram
&lt;/h3&gt;

&lt;p&gt;Here's a simple architecture diagram showing how Dozer can be used as a cache layer for a PostgreSQL database:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpar4c66qu63vqwunymjy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpar4c66qu63vqwunymjy.png" alt="architecture diagram of using Dozer as a cache layer for a PostgreSQL database" width="800" height="369"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In a nutshell:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Dozer begins by ingesting data in real-time from the PostgreSQL database using the PostgreSQL connector and stores this data in its cache.&lt;/li&gt;
&lt;li&gt;When a client sends a request for data, Dozer processes the request using the low-latency APIs it has generated, and retrieves the required data from its cache to serve the client.&lt;/li&gt;
&lt;li&gt;For write requests, these are facilitated through the backend API, which directly communicates with the PostgreSQL database. Once the write operation is confirmed, the PostgreSQL database sends a write confirmation back to the backend API.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The key point here is that data ingestion into Dozer's cache and the serving of data to the client through Dozer's APIs occur in parallel. This setup ensures quick and efficient access to data, enhancing the performance of your application."&lt;/p&gt;

&lt;p&gt;Dozer provides a &lt;a href="https://getdozer.io/docs/configuration/connectors/#postgresql" rel="noopener noreferrer"&gt;PostgreSQL connector&lt;/a&gt; that allows it to ingest data in real-time from your PostgreSQL database. The configuration can be as simple as the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;app_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;movie-booking&lt;/span&gt;
&lt;span class="na"&gt;connections&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;config&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!Postgres&lt;/span&gt;
      &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres&lt;/span&gt;
      &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres&lt;/span&gt;
      &lt;span class="na"&gt;host&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;0.0.0.0&lt;/span&gt;
      &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5438&lt;/span&gt;
      &lt;span class="na"&gt;database&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;database_name&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;connection_name&lt;/span&gt;

&lt;span class="na"&gt;sql&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
  &lt;span class="s"&gt;-- transformation and&lt;/span&gt;
  &lt;span class="s"&gt;-- analytical queries here.&lt;/span&gt;

&lt;span class="na"&gt;sources&lt;/span&gt;&lt;span class="pi"&gt;:&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;source_name_1&lt;/span&gt;
    &lt;span class="na"&gt;table_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;table_name&lt;/span&gt;
    &lt;span class="na"&gt;columns&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;connection&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!Ref&lt;/span&gt; &lt;span class="s"&gt;connection_name&lt;/span&gt;

  &lt;span class="s"&gt;...&lt;/span&gt;

&lt;span class="na"&gt;endpoints&lt;/span&gt;&lt;span class="pi"&gt;:&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;endpoint_name&lt;/span&gt;
    &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/endpoint_path&lt;/span&gt;
    &lt;span class="na"&gt;table_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;table_name&lt;/span&gt;
    &lt;span class="na"&gt;index&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;primary_key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;primary_key_column_name&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This configuration allows Dozer to ingest data in real-time from your PostgreSQL database and store it in a high-performance cache. This cache can then be used to serve low-latency data APIs to your application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Implementing Dozer with its ability to ingest data in real-time from PostgreSQL can significantly improve the performance of your application by reducing the time taken to access frequently used data. This approach can significantly enhance your application's performance, making it more efficient and responsive in today's demanding tech scenario. By leveraging Dozer's real-time SQL engine, automatic secondary indexing, and instant API generation, developers can drastically lower the cost, complexity, and effort involved in putting together the data infrastructure necessary to build data applications.&lt;/p&gt;

&lt;p&gt;Happy coding, Happy Data APIng! 🚀👩‍💻👨‍💻&lt;/p&gt;

</description>
      <category>postgres</category>
      <category>cache</category>
      <category>api</category>
      <category>systems</category>
    </item>
    <item>
      <title>Secure Your Data APIs with Dozer: Adding Authorization to APIs</title>
      <dc:creator>Abhishek Mishra</dc:creator>
      <pubDate>Thu, 25 May 2023 14:35:50 +0000</pubDate>
      <link>https://dev.to/getdozer/secure-your-data-apis-with-dozer-adding-authorization-to-apis-3pn5</link>
      <guid>https://dev.to/getdozer/secure-your-data-apis-with-dozer-adding-authorization-to-apis-3pn5</guid>
      <description>&lt;p&gt;In today's world of API-driven applications, securing access to data is very important. As the amount of data generated and consumed continues to grow, the need for reliable, and efficient data access management becomes increasingly critical. One essential aspect of data security is ensuring proper authorization for API calls, allowing only the right people, applications, and services to access the required data. Managing access control for your APIs is crucial to guarantee that only authorized users can access and perform specific actions. With the increasing complexity of API ecosystems, secure and efficient authentication and authorization mechanisms are necessary.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/getdozer/dozer" rel="noopener noreferrer"&gt;Dozer&lt;/a&gt; addresses this challenge by adding authorization layer to your data APIs in an efficient way. One of the ways Dozer provides authorization is through the use of &lt;a href="https://jwt.io/" rel="noopener noreferrer"&gt;JSON Web Tokens (JWT)&lt;/a&gt;. JWT is a widely used industry-standard method for representing claims securely between two parties. You can learn more about JWT &lt;a href="https://jwt.io/" rel="noopener noreferrer"&gt;here&lt;/a&gt;. Using JWT tokens simplifies the process of adding authorization to your data APIs.&lt;/p&gt;

&lt;p&gt;To demonstrate this, we'll build a simple movie ticket booking app that has two roles - user (public) and admin. The user can only book tickets and view their bookings, whereas the admin has full access to all the APIs. We will use &lt;a href="https://github.com/getdozer/dozer-js" rel="noopener noreferrer"&gt;&lt;code&gt;@dozerjs/dozer&lt;/code&gt;&lt;/a&gt; and &lt;a href="https://github.com/getdozer/dozer-react" rel="noopener noreferrer"&gt;&lt;code&gt;dozer-react&lt;/code&gt;&lt;/a&gt; to enhance the functionality of our app. &lt;code&gt;@dozerjs/dozer&lt;/code&gt; is a TypeScript wrapper over gRPC APIs generated by Dozer, facilitating seamless communication with Dozer, while &lt;code&gt;dozer-react&lt;/code&gt; provides a set of React helpers for using Dozer as a data provider. The sample application's repository can be found &lt;a href="https://github.com/getdozer/dozer-samples/tree/main/usecases/api-auth" rel="noopener noreferrer"&gt;here&lt;/a&gt;, you can aslo find the instructions to run the application directly.&lt;/p&gt;

&lt;p&gt;By following the step-by-step guide we've provided, you can safeguard your application from unauthorized access, ensuring data integrity and user trust.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Clone the repo and change to the project directory:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone git@github.com:getdozer/dozer-samples.git &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;dozer-samples/usecases/api-auth/
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Start the PostgreSQL database:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;database &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; docker-compose up &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd&lt;/span&gt; ..
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Generate and export a master token for auth:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dozer api generate-token
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;MASTER_TOKEN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;your_token_here
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Start the Dozer app:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dozer
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In a new terminal, install server dependencies and run the server app:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;server &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; yarn &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; node index.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In a new terminal, navigate to the &lt;code&gt;client&lt;/code&gt; directory, install client dependencies and start the app:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;    &lt;span class="nb"&gt;cd&lt;/span&gt; ../client &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; yarn &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; yarn start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Visit &lt;a href="https://dev.tolocalhost:3000"&gt;localhost:3000&lt;/a&gt; to use the app. For the admin dashboard, go to &lt;a href="https://dev.tolocalhost:3000/admin/dashboard"&gt;localhost:3000/admin/dashboard&lt;/a&gt; with "admin" as username and password.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;User Page&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5j83id5l2pnbt8np03hb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5j83id5l2pnbt8np03hb.png" alt="user page with list of movies to book" width="730" height="856"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Admin dashboard&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkq5kgf37c44s99u0jdsy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkq5kgf37c44s99u0jdsy.png" alt="admin dashboard showing realtime bookings" width="731" height="379"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbku1ofpkd7x3sa1sr36a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbku1ofpkd7x3sa1sr36a.png" alt="architecture of movie ticket booking app with dozer and postgresql for adding Authorization to dozer APIs " width="800" height="318"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this blog, we'll guide you through the process of constructing a movie ticket booking application using Dozer, React, and PostgreSQL. The PostgreSQL database is utilized directly in our server-side application to manage user creation and ticket bookings.&lt;/p&gt;

&lt;p&gt;To elaborate, the server app is specifically designed to handle user login, create new user entries, and register ticket bookings. It interacts directly with the PostgreSQL database to handle these tasks. The information required for booking tickets, such as booking details, is sent from the React frontend application to the Node.js server app, which then inserts these details into the PostgreSQL database.&lt;/p&gt;

&lt;p&gt;However, when it comes to consuming real-time data like the movie list, dashboard updates, or ongoing bookings, we use Dozer, which fetches the data from PostgreSQL using the PostgreSQL connector. This strategy allows us to get the most recent booking updates and display them on the dashboard in real-time.&lt;/p&gt;

&lt;p&gt;The PostgreSQL connector in Dozer bridges our database with the Dozer server and enables the seamless transfer of data in real-time. You can learn more about this connector at Dozer's documentation page here: &lt;a href="https://getdozer.io/docs/configuration/connectors#postgres" rel="noopener noreferrer"&gt;PostgreSQL Connector&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;On the client side, we're using a React app to display the movie data and booking interface, pulling data from Dozer. We employ the &lt;code&gt;@dozerjs/dozer&lt;/code&gt; and &lt;code&gt;dozer-react&lt;/code&gt; libraries to simplify interactions with Dozer and access real-time data without having to hardcode API endpoints in the code.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;@dozerjs/dozer&lt;/code&gt; library manages gRPC requests between the frontend and the Dozer server, allowing effective communication between the two. In contrast, the &lt;code&gt;dozer-react&lt;/code&gt; library provides a set of React helpers, making it simpler to use Dozer as a data provider in our React app. Find more about these libraries at their respective GitHub repositories: &lt;a href="https://github.com/getdozer/dozer-js" rel="noopener noreferrer"&gt;@dozerjs/dozer&lt;/a&gt; and &lt;a href="https://github.com/getdozer/dozer-react" rel="noopener noreferrer"&gt;dozer-react&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Let's dive into the process of building this application, demonstrating how you can leverage Dozer to amplify your app development experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  Server-Side Setup (Express.js)
&lt;/h2&gt;

&lt;p&gt;First, let's set up the server-side code using Express.js. The code is available in &lt;code&gt;server/index.js&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;express&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;ApiClient&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;AuthClient&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@dozerjs/dozer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;axios&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;axios&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cors&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;faker&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@faker-js/faker&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;//... Rest of the code&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We import the required libraries, including &lt;code&gt;express&lt;/code&gt;, &lt;code&gt;@dozerjs/dozer&lt;/code&gt;, &lt;code&gt;axios&lt;/code&gt;, &lt;code&gt;cors&lt;/code&gt;, and &lt;code&gt;@faker-js/faker&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Database Connection for Server-Side
&lt;/h3&gt;

&lt;p&gt;Setting up a connection with a PostgreSQL database is crucial to perform operations like user creation and booking entries. We accomplish this using the &lt;code&gt;pg&lt;/code&gt; client.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Client&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;pg&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;host&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;127.0.0.1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5432&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;database&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;omdb&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;postgres&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;postgres&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the configuration object, we specify the parameters like host, port, database name, user, and password. With the successful connection established via &lt;code&gt;client.connect()&lt;/code&gt;, we can execute queries to our database in our Express.js routes.&lt;/p&gt;

&lt;p&gt;This setup enables two primary functionalities in our application:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;User creation:&lt;/strong&gt; With the database connection ready, we can insert new user details into the &lt;code&gt;users&lt;/code&gt; table. This is used in the &lt;code&gt;/public/new_user&lt;/code&gt; endpoint, where a new user is created with a unique UUID and a randomly generated name.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Booking entries:&lt;/strong&gt; The connection also allows us to create new entries in the &lt;code&gt;bookings&lt;/code&gt; table. This functionality is used in the &lt;code&gt;/public/book_movie&lt;/code&gt; endpoint, where a user can book a movie, resulting in a new booking record in the database with the user's id and the provided movie id.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Admin Login Endpoint
&lt;/h3&gt;

&lt;p&gt;This endpoint validates the provided username and password. If valid, a post request is made to the authentication server to get a token. The token is then sent back to the client. Error handling is also set up to send a 500 status code in case of a server error and a 400 status code for incorrect credentials.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/admin/login&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="c1"&gt;// Check if the provided credentials are valid&lt;/span&gt;
    &lt;span class="c1"&gt;// Generate JWT token with full access to all API endpoints&lt;/span&gt;
    &lt;span class="c1"&gt;// Send the JWT token to the client&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Public New User Endpoint
&lt;/h3&gt;

&lt;p&gt;The new user endpoint generates a random username and UUID using the &lt;code&gt;faker&lt;/code&gt; library. It then inserts this new user into the database. After successful insertion, a JWT token is generated for the new user with limited access. Error handling is set up in case the server encounters an error while processing the request.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/public/new_user&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="c1"&gt;// Generate random username and UUID&lt;/span&gt;
    &lt;span class="c1"&gt;// Insert new user into the database&lt;/span&gt;
    &lt;span class="c1"&gt;// Generate JWT token with limited access for the new user&lt;/span&gt;
    &lt;span class="c1"&gt;// Handle server errors&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Public Book Movie Endpoint
&lt;/h3&gt;

&lt;p&gt;The book movie endpoint allows users to book a movie by sending their JWT token in the headers. The server first validates the user's token. If valid, it inserts a new record in the bookings table in the database with the user's id and the provided movie id. The response includes error handling as well.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/public/book_movie&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="c1"&gt;// Validate the user's token&lt;/span&gt;
    &lt;span class="c1"&gt;// Insert a new record in the bookings table&lt;/span&gt;
    &lt;span class="c1"&gt;// Handle server errors&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Error Handling Middleware
&lt;/h3&gt;

&lt;p&gt;Lastly, we also add a middleware function to handle any errors that may slip through our route handlers. This middleware logs the error and sends a generic error message to the client.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// log the error, for now just console.log&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Something broke!&lt;/span&gt;&lt;span class="dl"&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;After setting up these routes, the Express.js application is ready to listen for requests on port 4000.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our error handling middleware ensures that any errors that occur during these database operations are effectively captured and appropriately communicated to the user.&lt;br&gt;
In this way, our server is set up to handle the creation of new users, allow users to book movies, and allow an admin to log in, all while ensuring errors are handled appropriately. .&lt;/p&gt;
&lt;h2&gt;
  
  
  Database Setup For Movie data (PostgreSQL)
&lt;/h2&gt;

&lt;p&gt;We use PostgreSQL as our database, and the configuration is available in the &lt;code&gt;docker-compose.yml&lt;/code&gt; file. The file defines a &lt;code&gt;postgres&lt;/code&gt; service, which includes the container name, image, volumes, and environment variables.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&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;3.8'&lt;/span&gt;
&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;postgres&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;omdb-postgres&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;debezium/postgres:13&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./pg_hba.conf:/var/lib/foo/pg_hba.conf&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./data/init.sql:/docker-entrypoint-initdb.d/init.sql&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./data:/data&lt;/span&gt;
    &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres -c hba_file=/var/lib/foo/pg_hba.conf&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;POSTGRES_DB&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;omdb&lt;/span&gt;
      &lt;span class="na"&gt;POSTGRES_USER&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres&lt;/span&gt;
      &lt;span class="na"&gt;POSTGRES_PASSWORD&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres&lt;/span&gt;
      &lt;span class="na"&gt;ALLOW_IP_RANGE&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;0.0.0.0/0&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;5438:5432'&lt;/span&gt;
    &lt;span class="na"&gt;healthcheck&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CMD-SHELL"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;pg_isready&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;-U&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;postgres&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;-d&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;omdb"&lt;/span&gt; &lt;span class="pi"&gt;]&lt;/span&gt;
      &lt;span class="na"&gt;interval&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;5s&lt;/span&gt;
      &lt;span class="na"&gt;timeout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;5s&lt;/span&gt;
      &lt;span class="na"&gt;retries&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The database is populated with the Open Movie Database (OMDB) dataset, which provides a comprehensive list of movie-related data. For further details about this dataset, you can visit the official OMDB repository here: &lt;a href="https://github.com/credativ/omdb-postgresql" rel="noopener noreferrer"&gt;OMDB on GitHub&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Front-End Setup (React)
&lt;/h2&gt;

&lt;p&gt;The frontend of our application is designed with React, a popular JavaScript library used for building interactive UIs. The frontend setup for our movie booking application involves a series of React components that interact with our backend server using HTTP requests. These components handle user authentication, data fetching, and real-time updates to ensure users have an interactive and up-to-date interface.&lt;/p&gt;

&lt;p&gt;Let's take a look at the structure of our project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;├── README.md
├── package.json
├── src
│   ├── App.css
│   ├── App.js
│   ├── App.test.js
│   ├── components
│   │   ├── admin
│   │   │   └── dashboard.js
│   │   ├── login.js
│   │   └── public
│   │       ├── movies.js
│   │       └── moviesList.js
│   ├── index.css
│   ├── index.js
│   ...
└── yarn.lock
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our React components are placed in the &lt;code&gt;src/components&lt;/code&gt; directory, separated by user type (public users and admins).&lt;/p&gt;

&lt;h3&gt;
  
  
  Login Component
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;login.js&lt;/code&gt; component facilitates the login functionality for the admin users. It includes text fields for the admin to enter their username and password, and a login button to submit the login details.&lt;/p&gt;

&lt;p&gt;On submission, a &lt;code&gt;POST&lt;/code&gt; request is made to the &lt;code&gt;http://localhost:4000/admin/login&lt;/code&gt; endpoint with the username and password as the body of the request. If the credentials are valid, the response will contain a token, which is stored in the browser's local storage and used to authenticate future requests.&lt;/p&gt;

&lt;h3&gt;
  
  
  Admin Dashboard Component
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;dashboard.js&lt;/code&gt; component acts as the main interface for admin users. On load, it checks if a token exists in local storage. If not, it redirects the user to the login page.&lt;/p&gt;

&lt;p&gt;Using the &lt;code&gt;movies_with_bookings&lt;/code&gt; query, it fetches the list of movies with their booking counts and displays them in a table. This component uses real-time updates to ensure the admin always has the most current booking data.&lt;/p&gt;

&lt;h3&gt;
  
  
  Movie List Component
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;moviesList.js&lt;/code&gt; component displays the list of movies and their current booking counts to public users. It allows users to "buy" a ticket for a movie, which is simulated by making a &lt;code&gt;POST&lt;/code&gt; request to the &lt;code&gt;http://localhost:4000/public/book_movie&lt;/code&gt; endpoint with the selected movie's id. The state of this component is updated in real-time as bookings are made.&lt;/p&gt;

&lt;h3&gt;
  
  
  Movies Component
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;movies.js&lt;/code&gt; component acts as a wrapper for the &lt;code&gt;moviesList.js&lt;/code&gt; component. On load, it checks for a token in local storage. If a token doesn't exist, it makes a &lt;code&gt;GET&lt;/code&gt; request to the &lt;code&gt;http://localhost:4000/public/new_user&lt;/code&gt; endpoint to generate a new token. Once a token is obtained, it passes the token as a prop to the &lt;code&gt;MoviesList&lt;/code&gt; component.&lt;/p&gt;

&lt;h2&gt;
  
  
  Integrating Dozer JWT in the Application
&lt;/h2&gt;

&lt;p&gt;Having established the foundation of our application in the previous sections, it's time to delve into the secure integration of JWT authentication and Role-Based Access Control (RBAC) using Dozer. Our focus will be on illustrating how this can be applied in our movie ticket booking application.&lt;/p&gt;

&lt;p&gt;Outlined below are the key steps to enable secure API authorization in your application:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Generate a master token using Dozer's API server.&lt;/li&gt;
&lt;li&gt;Using the master token, generate custom access tokens for each set of APIs to establish granular-level access.&lt;/li&gt;
&lt;li&gt;Incorporate the generated custom access tokens in subsequent client-side API calls.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  1. Master JWT Token Generation
&lt;/h3&gt;

&lt;p&gt;Kick off the process by running the following command to generate a master JWT token:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dozer api generate-token
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command triggers the generation of the master token, which is outputted to stdout. The master token has the privilege of accessing all API endpoints specified in the config file. To access the APIs, include the token in your request header as demonstrated below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;MASTER_TOKEN&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;your_master_token_here&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Custom Access Token Generation
&lt;/h3&gt;

&lt;p&gt;For a more granular access control, Dozer allows for the creation of custom access tokens for specific API calls. These tokens can be generated through a POST request to the &lt;code&gt;/auth/token&lt;/code&gt; endpoint, providing an access filter and the previously generated &lt;code&gt;MASTER_TOKEN&lt;/code&gt; in the request header.&lt;/p&gt;

&lt;p&gt;This affords you the opportunity to designate specific access controls for different users or roles within your application. For a more detailed guide on this, you may refer to the Dozer documentation page on &lt;a href="https://getdozer.io/docs/configuration/security" rel="noopener noreferrer"&gt;Authentication &amp;amp; Authorization&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In the context of our movie ticket booking app, we generate a JWT token comprising the necessary access controls whenever an admin logs in or a new user is registered. This token is then dispatched to the client and utilized in future API calls.&lt;/p&gt;

&lt;p&gt;Here is an illustration of the token generation process in the &lt;code&gt;index.js&lt;/code&gt; file located in the &lt;code&gt;server&lt;/code&gt; directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//...other code&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;MASTER_TOKEN&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MASTER_TOKEN&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/admin/login&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="c1"&gt;//...other code&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;All&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;post&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http://127.0.0.1:8080/auth/token&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Authorization&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Bearer &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;MASTER_TOKEN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="na"&gt;data&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="c1"&gt;//...other code&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Furthermore, we can customize the access token to limit access based on the user's role:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//...other code&lt;/span&gt;
&lt;span class="c1"&gt;// Generate token with limited access based on user role&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
   &lt;span class="c1"&gt;//...other code&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="c1"&gt;//...other code&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the code snippet above, the custom access token restricts access to only the &lt;code&gt;need_to_Add_endpoint_name&lt;/code&gt; API endpoint. The access filter can be tweaked to include other endpoints and set specific permissions anchored on user roles.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Incorporating Tokens in Client-Side API Calls
&lt;/h3&gt;

&lt;p&gt;Once the JWT tokens are generated, they can be utilized client-side for secure API access. This can be seen in the &lt;code&gt;movies.js&lt;/code&gt; file and other components housed in the &lt;code&gt;public&lt;/code&gt; directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//...other code&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Movies&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setToken&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;public_jwt&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;setToken&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;public_jwt&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;//...other code&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;span class="c1"&gt;//...other code&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Whenever the client makes an API call, the server validates the JWT token and checks if the user has the necessary permissions to access the requested endpoint. If the token is valid and the user will get the valid response.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping Up:
&lt;/h2&gt;

&lt;p&gt;Using Dozer's powerful security capabilities, you can easily add authorization to your data APIs, ensuring that your application remains secure and accessible only to authorized users. Whether you're building a movie ticket app or any other application, Dozer provides a flexible and straightforward way to manage access control for your APIs.&lt;/p&gt;

&lt;p&gt;The beauty of Dozer lies in its flexibility—it moulds itself according to your needs, allowing you to craft custom access controls for different user roles, thereby ensuring the right balance between functionality and security.&lt;/p&gt;

&lt;p&gt;Through our movie ticket booking application, we've demonstrated just a fragment of the potential that Dozer holds. Regardless of your application's domain—be it e-commerce, social media, healthcare, or any other field—you can leverage the power of Dozer to secure your data APIs.&lt;/p&gt;

&lt;p&gt;In conclusion, Dozer presents a robust, scalable, and straightforward solution to facilitate API security and data management. It's a testament to the flexibility of modern software tools and their ability to adapt to a wide range of application needs. We hope this guide has clarified the process of secure API management and inspired you to integrate Dozer into your next project.&lt;/p&gt;

&lt;p&gt;Happy coding, Happy Data APIng! 🚀👩‍💻👨‍💻&lt;/p&gt;

</description>
      <category>postgres</category>
      <category>react</category>
      <category>api</category>
      <category>security</category>
    </item>
    <item>
      <title>Announcing the Dozer Appathon!</title>
      <dc:creator>Abhishek Mishra</dc:creator>
      <pubDate>Wed, 03 May 2023 05:59:55 +0000</pubDate>
      <link>https://dev.to/getdozer/announcing-the-dozer-appathon-2oo7</link>
      <guid>https://dev.to/getdozer/announcing-the-dozer-appathon-2oo7</guid>
      <description>&lt;p&gt;👋🏼 Are you looking for a platform that simplifies the process of building and deploying data-driven applications? Look no further than &lt;a href="https://getdozer.io/" rel="noopener noreferrer"&gt;Dozer&lt;/a&gt; ! 💻 is a &lt;strong&gt;powerful Data API backend&lt;/strong&gt; that simplifies the process of building and deploying data-driven applications &amp;amp; APIs for real-time data processing and analysis, predictive analytics, data caching, and much more.&lt;/p&gt;

&lt;p&gt;And now, you have the chance to showcase your coding skills and creativity by participating in the Dozer Appathon! 🚀 This exciting event is open to everyone who is interested in building applications with Dozer. The submission period runs from &lt;strong&gt;May 3 to May 9, 2023&lt;/strong&gt;; so you still have time to get your app ready! ⏰&lt;/p&gt;

&lt;h2&gt;
  
  
  Dozer Appathon Hacker Guide 👩‍💻👨‍💻
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5y5e7r7n16hyeur5p6kn.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5y5e7r7n16hyeur5p6kn.gif" alt="Hero" width="498" height="280"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction 🚀
&lt;/h2&gt;

&lt;p&gt;Welcome to the Dozer Appathon! This is your chance to showcase your coding skills and creativity by building amazing applications using our platform. &lt;a href="https://getdozer.io/" rel="noopener noreferrer"&gt;Dozer&lt;/a&gt; is a &lt;strong&gt;powerful Data API backend&lt;/strong&gt; that simplifies the process of building and deploying data-driven applications &amp;amp; APIs. &lt;/p&gt;

&lt;h2&gt;
  
  
  Sample use cases📝
&lt;/h2&gt;

&lt;p&gt;To help you get started, we have prepared a list of sample use cases and ideas for your app. You can use these as inspiration for your project, or come up with your own unique ideas.&lt;/p&gt;

&lt;h3&gt;
  
  
  Some sample use cases are
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- Real-time data processing and analysis
- Data aggregation and consolidation from multiple sources
- Machine learning and predictive analytics
- Data caching and optimization for faster performance
- IoT data processing and analysis
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Some wonderful project ideas💡
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Real-time Eth layer 2 crypto dashboard📈&lt;/li&gt;
&lt;li&gt;NodeJS-based Twilio notifications with real-time alerts using Dozer📲&lt;/li&gt;
&lt;li&gt;Real-time ML predictions using ONNX model🧠&lt;/li&gt;
&lt;li&gt;React Native push notifications📱&lt;/li&gt;
&lt;li&gt;Klarna clone with user profiles and transactions in React Native💳&lt;/li&gt;
&lt;li&gt;Real-time vehicle tracking on Google Maps with traffic density alerts (Web or React Native)🚗&lt;/li&gt;
&lt;li&gt;Real-time inventory dashboard for a retail chain with multiple warehouses🛍️&lt;/li&gt;
&lt;li&gt;Fraud detection for credit card transactions using ML models on Python Lambda💳🕵️‍♂️&lt;/li&gt;
&lt;li&gt;Model training and scoring with data injection through Python Lambda 🧑‍💻📈&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Prizes 🎁
&lt;/h2&gt;

&lt;p&gt;We have some exciting prizes up for grabs!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The top 5 submissions will win an amazing Mechanical Keyboard and a Dozer branded Swagpack 🏆&lt;/li&gt;
&lt;li&gt;The next 10 successful submissions win Dozer Branded swagpack which includes an awesome tee and stickers. 🎉&lt;/li&gt;
&lt;li&gt;Additionally, all participants will receive a certificate of participation.📜&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Resources 📚
&lt;/h2&gt;

&lt;p&gt;To help you build your app, we have some resources for you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Website: &lt;a href="https://getdozer.io/" rel="noopener noreferrer"&gt;https://getdozer.io/&lt;/a&gt; 🌐&lt;/li&gt;
&lt;li&gt;Docs: &lt;a href="https://getdozer.io/docs/dozer" rel="noopener noreferrer"&gt;https://getdozer.io/docs/dozer&lt;/a&gt; 📖&lt;/li&gt;
&lt;li&gt;Blogs: &lt;a href="https://getdozer.io/blog" rel="noopener noreferrer"&gt;https://getdozer.io/blog&lt;/a&gt; 📰&lt;/li&gt;
&lt;li&gt;Blog Tutorial: &lt;a href="https://getdozer.io/blog/building-real-time-data-app-using-dozer-react-postgresql/" rel="noopener noreferrer"&gt;https://getdozer.io/blog/building-real-time-data-app-using-dozer-react-postgresql/&lt;/a&gt; 📚&lt;/li&gt;
&lt;li&gt;Video Tutorial: &lt;a href="https://youtu.be/pVfyMfNrlD4" rel="noopener noreferrer"&gt;https://youtu.be/pVfyMfNrlD4&lt;/a&gt; 📹&lt;/li&gt;
&lt;li&gt;Discord Community support: If you have any questions or need help with your project, you can reach out to &lt;code&gt;#dozer-appathon&lt;/code&gt; channel of the &lt;a href="https://discord.gg/9TeAVfF34S" rel="noopener noreferrer"&gt;Dozer Discord&lt;/a&gt; for support. 💬&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Judging Criteria 🧐
&lt;/h2&gt;

&lt;p&gt;We will rate as per optimal utilisation of Dozer in your app on a scale of 0-10, based on factors like &lt;code&gt;real-time data, multiple data sources, and caching requirements&lt;/code&gt;. We'll also consider the problem you're solving and the code quality of your app.&lt;/p&gt;

&lt;h2&gt;
  
  
  Submission Method 📩
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Submit a PR following the &lt;a href="https://github.com/getdozer/dozer-samples/tree/main/community-samples" rel="noopener noreferrer"&gt;Contribution Guidelines&lt;/a&gt; with  your project detail.&lt;/li&gt;
&lt;li&gt;Fill out &lt;a href="https://forms.gle/hoqPqS4qLJAnBpaWA" rel="noopener noreferrer"&gt;this form&lt;/a&gt; post PR submission.&lt;/li&gt;
&lt;li&gt;Winners will be announced in the &lt;a href="https://discord.gg/9TeAVfF34S" rel="noopener noreferrer"&gt;Discord Server&lt;/a&gt;.💪🏆&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Stargazers’ Raffle✨
&lt;/h2&gt;

&lt;p&gt;Star our &lt;a href="https://github.com/getdozer/dozer" rel="noopener noreferrer"&gt;repository&lt;/a&gt; and get a chance to win an amazing Swagpack!!🎁🎉&lt;br&gt;
We will announce the winners in our Discord server. So, don’t forget to &lt;a href="https://discord.gg/9TeAVfF34S" rel="noopener noreferrer"&gt;join&lt;/a&gt;.🤗&lt;/p&gt;

&lt;p&gt;We're excited to see what you can create with Dozer!&lt;br&gt;
Good luck and Happy Hacking!, Happy Data APIng 🚀 👩‍💻👨‍💻&lt;/p&gt;

&lt;p&gt;For more details, checkout: &lt;a href="https://getdozer.io/blog/dozer-appathon" rel="noopener noreferrer"&gt;https://getdozer.io/blog/dozer-appathon&lt;/a&gt;&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>hackathon</category>
      <category>api</category>
      <category>developer</category>
    </item>
    <item>
      <title>Unleashing the Power of Dozer Lambda Runtime for Real-time and Event-driven Data Apps</title>
      <dc:creator>Abhishek Mishra</dc:creator>
      <pubDate>Tue, 02 May 2023 14:21:50 +0000</pubDate>
      <link>https://dev.to/getdozer/unleashing-the-power-of-dozer-lambda-runtime-for-real-time-and-event-driven-data-apps-cn3</link>
      <guid>https://dev.to/getdozer/unleashing-the-power-of-dozer-lambda-runtime-for-real-time-and-event-driven-data-apps-cn3</guid>
      <description>&lt;p&gt;Real-time data processing is essential for modern applications, as it ensures that insights are timely and accurate. The open-source project Dozer now provides a runtime environment that allows developers to execute lambda functions or custom user-defined functions based on specific data conditions.&lt;br&gt;
This new functionality allows for more dynamic and event-driven applications, as Lambda functions can be triggered based on specific data change conditions. Just imagine triggering a Twilio notification based on a SQL statement (data change condition)!&lt;/p&gt;

&lt;p&gt;In this blog post, we will discuss how you can use Dozer to respond to real-time data changes by triggering functions based on data conditions.&lt;br&gt;
In this &lt;a href="https://github.com/getdozer/dozer-samples/tree/main/usecases/lambda" rel="noopener noreferrer"&gt;example&lt;/a&gt;, we will create a React app that generates a real-time graph based on room temperature data (room temperature monitoring). We will use the &lt;a href="https://github.com/getdozer/dozer/tree/main/dozer-log-python" rel="noopener noreferrer"&gt;&lt;code&gt;pydozer_log&lt;/code&gt;&lt;/a&gt; module to react to data change conditions and trigger a Twilio message if the room temperature goes above 22.9°C.&lt;/p&gt;
&lt;h2&gt;
  
  
  Dozer Lambda Runtime: A Glimpse
&lt;/h2&gt;

&lt;p&gt;The Dozer Lambda runtime is a major enhancement to the Dozer project, enabling developers to write Lambda functions in JavaScript and Python that react to Dozer events.&lt;/p&gt;

&lt;p&gt;To help you better understand the Dozer Lambda runtime, we will examine the following state diagram:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5jh34ullovt53iun1pnx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5jh34ullovt53iun1pnx.png" alt="dozer lambda runtime" width="778" height="307"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;DCC: Data Change Condition&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Data Source: Your application's data source, such as a database, sends data to the Dozer pipeline.&lt;/li&gt;
&lt;li&gt;Dozer Pipeline: The data is processed through the Dozer pipeline, which can apply various transformations and aggregations based on the configuration you provide.&lt;/li&gt;
&lt;li&gt;Lambda Runtime: The Dozer Lambda runtime monitors the pipeline for specific data change conditions that you define. If a data change condition is met, the corresponding Lambda function is triggered.&lt;/li&gt;
&lt;li&gt;Action/Trigger: The triggered Lambda function performs the desired action, such as sending a Twilio notification or updating a database record.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The reponse of trigger can be used to write back top dozer, for example using gRPC service.&lt;/p&gt;
&lt;h3&gt;
  
  
  JavaScript and Python Bindings for Reading Dozer Logs
&lt;/h3&gt;

&lt;p&gt;Dozer now provides bindings for both JavaScript and Python to read logs, making it easier for developers to work with the languages they are most comfortable with. These bindings are essential components of the Dozer Lambda runtime, as they enable developers to create Lambda functions that respond to&lt;br&gt;
events.&lt;/p&gt;
&lt;h2&gt;
  
  
  React App Example: Room Temperature Monitoring
&lt;/h2&gt;

&lt;p&gt;In this example, we will create a React app that generates a real-time graph based on room temperature data. We will use the pydozer_log module to react to data change conditions and trigger a Twilio message if the room temperature goes above 22.9°C.&lt;/p&gt;

&lt;p&gt;Here are the steps to run the app:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Clone the &lt;a href="https://github.com/getdozer/dozer-samples" rel="noopener noreferrer"&gt;Dozer Samples repository&lt;/a&gt; and install dependencies:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/getdozer/dozer-samples.git
&lt;span class="nb"&gt;cd &lt;/span&gt;dozer-samples/usecases/lambda/
pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;Remove any existing Dozer configuration and start the Dozer:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; ./.dozer &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; dozer &lt;span class="nt"&gt;-c&lt;/span&gt; config/dozer-config.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;Run the Python scripts to read data from the pipeline:&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Note: make sure to replace the Twilio configuration in &lt;code&gt;reader.py&lt;/code&gt;, with your account id and auth token. To learn more about Twilio SMS setup checkout this &lt;a href="https://www.twilio.com/docs/sms/quickstart/python" rel="noopener noreferrer"&gt;getting started guide.&lt;/a&gt;&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;


&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python reader.py
python main.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Navigate to the React app folder, install the necessary packages, and start the development server:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;react
yarn &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; yarn start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5zkrnl7k0iisbpxp2z8u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5zkrnl7k0iisbpxp2z8u.png" alt="reach app showing a graph of room temperature monitoring" width="800" height="465"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once the app is running, you should see a real-time graph of the room temperature data. If the temperature exceeds 22.9°C, a Twilio message will be triggered, notifying the relevant parties of the situation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh55yk011z1db3w7f6qgi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh55yk011z1db3w7f6qgi.png" alt="twilio message after temperature exceeds 22.9°C" width="800" height="995"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion 🎯
&lt;/h2&gt;

&lt;p&gt;By using the Dozer Lambda runtime, you can create event-driven applications that automatically respond to changes in your data, making your applications more efficient, scalable, and responsive to user needs. By leveraging the Python and JavaScript libraries provided by Dozer, developers can easily build applications that respond to real-time data changes, making it an invaluable resource for modern applications.&lt;/p&gt;

&lt;p&gt;Happy coding, Happy Data APIng! 🚀👩‍💻👨‍💻&lt;/p&gt;

</description>
      <category>lambda</category>
      <category>eventdriven</category>
      <category>react</category>
      <category>twilio</category>
    </item>
    <item>
      <title>🚀 Getting Started with Dozer with Docker: A Step-by-Step Tutorial</title>
      <dc:creator>Abhishek Mishra</dc:creator>
      <pubDate>Mon, 24 Apr 2023 14:00:00 +0000</pubDate>
      <link>https://dev.to/getdozer/getting-started-with-dozer-with-docker-a-step-by-step-tutorial-5ge2</link>
      <guid>https://dev.to/getdozer/getting-started-with-dozer-with-docker-a-step-by-step-tutorial-5ge2</guid>
      <description>&lt;p&gt;In the world of data-driven applications, accessing and manipulating data in real-time is crucial. Dozer is a powerful tool that helps you create low-latency data APIs (gRPC and REST) from any data source, enabling seamless integration with frontend applications. In this tutorial, we'll walk you through setting up Dozer with Docker and connecting it to PostgreSQL using Docker.&lt;/p&gt;

&lt;h3&gt;
  
  
  🌟 Why Dozer?
&lt;/h3&gt;

&lt;p&gt;&lt;a href="[https](https://github.com/getdozer/dozer)"&gt;Dozer&lt;/a&gt; addresses the challenges of accessing and manipulating data in real-time by providing an easy-to-use solution to create efficient data APIs. With Dozer, you can quickly set up APIs that can be easily integrated with your frontend applications. Furthermore, using Docker allows you to containerize your application, making it portable and easy to manage.&lt;/p&gt;

&lt;p&gt;In this step-by-step tutorial, we'll guide you through connecting PostgreSQL with Dozer using Docker. Let's get started!&lt;/p&gt;

&lt;h3&gt;
  
  
  🔧 Prerequisites:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Docker/Docker desktop installed on your machine&lt;/li&gt;
&lt;li&gt;Basic knowledge of Docker and PostgreSQL&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;📝 Overall steps involved:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a &lt;code&gt;docker-compose&lt;/code&gt; file for PostgreSQL&lt;/li&gt;
&lt;li&gt;Create a Dozer config with PostgreSQL connector and API configuration&lt;/li&gt;
&lt;li&gt;Run PostgreSQL (via Docker)&lt;/li&gt;
&lt;li&gt;Run Dozer (via Docker)&lt;/li&gt;
&lt;li&gt;Query your API&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🔹 Step 1: Create a &lt;code&gt;docker-compose.yml&lt;/code&gt; file
&lt;/h3&gt;

&lt;p&gt;First, create a &lt;code&gt;docker-compose.yml&lt;/code&gt; file and copy the following configuration to it or download the file here:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&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;3.9'&lt;/span&gt;
&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;postgres&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;platform&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;linux/amd64&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;quick-start-postgres&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;public.ecr.aws/getdozer/dozer-samples-pg-stocks:latest&lt;/span&gt;
    &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres -c hba_file=/var/lib/stock-sample/pg_hba.conf&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;POSTGRES_DB&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;stocks&lt;/span&gt;
      &lt;span class="na"&gt;POSTGRES_USER&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres&lt;/span&gt;
      &lt;span class="na"&gt;POSTGRES_PASSWORD&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres&lt;/span&gt;
      &lt;span class="na"&gt;ALLOW_IP_RANGE&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;0.0.0.0/0&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;5434:5432'&lt;/span&gt;
    &lt;span class="na"&gt;healthcheck&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CMD-SHELL"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;pg_isready&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;-U&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;postgres&lt;/span&gt;&lt;span class="nv"&gt;  &lt;/span&gt;&lt;span class="s"&gt;-h&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;0.0.0.0&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;-d&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;stocks"&lt;/span&gt; &lt;span class="pi"&gt;]&lt;/span&gt;
      &lt;span class="na"&gt;interval&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;5s&lt;/span&gt;
      &lt;span class="na"&gt;timeout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;5s&lt;/span&gt;
      &lt;span class="na"&gt;retries&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;

&lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;sample-data&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  🔹 Step 2: Create a Dozer config file
&lt;/h3&gt;

&lt;p&gt;Next, create a &lt;code&gt;dozer-config.yaml&lt;/code&gt; file with the following content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;app_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;1-hypercharge-postgres-sample&lt;/span&gt;
&lt;span class="na"&gt;connections&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;config&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!Postgres&lt;/span&gt;
      &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres&lt;/span&gt;
      &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres&lt;/span&gt;
      &lt;span class="na"&gt;host&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;host.docker.internal&lt;/span&gt;
      &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5434&lt;/span&gt;
      &lt;span class="na"&gt;database&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;stocks&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;stocks&lt;/span&gt;
&lt;span class="na"&gt;sources&lt;/span&gt;&lt;span class="pi"&gt;:&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;stocks&lt;/span&gt;
    &lt;span class="na"&gt;table_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;stocks&lt;/span&gt;
    &lt;span class="na"&gt;columns&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;id&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;ticker&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;date&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;open&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;high&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;low&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;close&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;adj_close&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;volume&lt;/span&gt;
    &lt;span class="na"&gt;connection&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!Ref&lt;/span&gt; &lt;span class="s"&gt;stocks&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;stocks_meta&lt;/span&gt;
    &lt;span class="na"&gt;table_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;stocks_meta&lt;/span&gt;
    &lt;span class="na"&gt;columns&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;symbol&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;security_name&lt;/span&gt;
    &lt;span class="na"&gt;connection&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!Ref&lt;/span&gt; &lt;span class="s"&gt;stocks&lt;/span&gt;
&lt;span class="na"&gt;endpoints&lt;/span&gt;&lt;span class="pi"&gt;:&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;stocks&lt;/span&gt;
    &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/stocks&lt;/span&gt;
    &lt;span class="na"&gt;table_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;stocks&lt;/span&gt;
    &lt;span class="na"&gt;index&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;primary_key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;id&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&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;stocks_meta&lt;/span&gt;
    &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/stocks-meta&lt;/span&gt;
    &lt;span class="na"&gt;table_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;stocks_meta&lt;/span&gt;
    &lt;span class="na"&gt;index&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;primary_key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;symbol&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  🔹 Step 3: Run PostgreSQL with sample stock data
&lt;/h3&gt;

&lt;p&gt;Open a terminal or command prompt and navigate to the directory containing the &lt;code&gt;docker-compose.yml&lt;/code&gt; file. Run the following command to start PostgreSQL with sample stock data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker-compose up
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  🔹 Step 4: Run Dozer with PostgreSQL connector (via Docker)
&lt;/h3&gt;

&lt;p&gt;Open another terminal or command prompt and navigate to the directory containing the &lt;code&gt;dozer-config.yaml&lt;/code&gt; file. To run Dozer as a Docker container, execute the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;-it&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
       &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$PWD&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;:/usr/dozer &lt;span class="se"&gt;\&lt;/span&gt;
       &lt;span class="nt"&gt;-p&lt;/span&gt; 8080:8080 &lt;span class="se"&gt;\&lt;/span&gt;
       &lt;span class="nt"&gt;-p&lt;/span&gt; 50051:50051 &lt;span class="se"&gt;\&lt;/span&gt;
       &lt;span class="nt"&gt;--platform&lt;/span&gt; linux/amd64 &lt;span class="se"&gt;\&lt;/span&gt;
       public.ecr.aws/k7k6x1d4/dozer &lt;span class="se"&gt;\&lt;/span&gt;
       dozer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Congratulations 🥳 , you should see Dozer up and running!&lt;/p&gt;

&lt;h3&gt;
  
  
  🎉 Query your API
&lt;/h3&gt;

&lt;p&gt;Dozer automatically generates APIs in both REST and gRPC formats, along with documentation, &lt;a href="https://swagger.io/specification/" rel="noopener noreferrer"&gt;OpenAPI&lt;/a&gt;, and proto files. In the following sections, we'll showcase some possible queries. Refer to the APIs section for more details.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🔸 Query Using gRPC:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You can use &lt;a href="https://github.com/fullstorydev/grpcurl" rel="noopener noreferrer"&gt;gRPCurl&lt;/a&gt; or &lt;a href="https://www.postman.com//download" rel="noopener noreferrer"&gt;Postman&lt;/a&gt; to interact with gRPC APIs.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;gRPC query example:&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;grpcurl &lt;span class="nt"&gt;-plaintext&lt;/span&gt; localhost:50051 dozer.generated.stocks_meta.StocksMetas/query
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;🔸 Query Using REST:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You can use curl or Postman to interact with REST APIs.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;REST query example:&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;--location&lt;/span&gt; &lt;span class="nt"&gt;--request&lt;/span&gt; GET &lt;span class="s1"&gt;'localhost:8080/stocks-meta'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it! You've successfully set up Dozer with Docker and connected it to PostgreSQL. Now you can easily create APIs for your data and integrate them into your frontend applications.&lt;/p&gt;

&lt;p&gt;If you're interested in learning more about how to use Dozer with applications, we recommend reading our previous blog post: &lt;a href="https://dev.to/getdozer/building-a-real-time-data-app-with-dozer-react-and-postgresql-391n"&gt;"Building a Real-Time Data App with Dozer, React, and PostgreSQL"&lt;/a&gt;. In this blog, you'll find a detailed tutorial that demonstrates how to integrate Dozer with a React frontend application and PostgreSQL as a data source. This comprehensive guide will give you a better understanding of how to build powerful, real-time data-driven applications using Dozer.&lt;/p&gt;

&lt;p&gt;Happy coding, Happy Data APIng! 🚀👩‍💻👨‍💻&lt;/p&gt;

</description>
      <category>docker</category>
      <category>postgres</category>
      <category>dozer</category>
      <category>api</category>
    </item>
    <item>
      <title>Dozer Goes Open Source: Empowering the Community to Build Real-time Data Apps</title>
      <dc:creator>Abhishek Mishra</dc:creator>
      <pubDate>Fri, 21 Apr 2023 15:56:07 +0000</pubDate>
      <link>https://dev.to/getdozer/dozer-goes-open-source-empowering-the-community-to-build-real-time-data-apps-5dd6</link>
      <guid>https://dev.to/getdozer/dozer-goes-open-source-empowering-the-community-to-build-real-time-data-apps-5dd6</guid>
      <description>&lt;p&gt;We are excited to announce that Dozer, a powerful platform for building low-latency data APIs (gRPC and REST) from any data source, is now open source! &lt;a href="https://www.apache.org/licenses/LICENSE-2.0.html" rel="noopener noreferrer"&gt;The Apache 2.0 license&lt;/a&gt; 🎉. With this move, we aim to empower the community to build and scale &lt;a href="https://www.splunk.com/en_us/data-insider/what-is-real-time-data.html" rel="noopener noreferrer"&gt;real-time data&lt;/a&gt; applications more effectively.&lt;/p&gt;

&lt;p&gt;Dozer simplifies the process of connecting applications to various data sources, such as PostgreSQL, Kafka, or other databases &amp;amp; sources, enabling developers to easily create and manage real-time data APIs. By making Dozer open source, we are inviting developers to contribute to its growth and help shape the future of real-time data applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Dozer?
&lt;/h2&gt;

&lt;p&gt;Dozer is a platform that enables developers to build low-latency data APIs (gRPC and REST) from any data source. It simplifies the process of connecting applications to data sources like databases, APIs, or other services, and automatically manages data streaming and synchronization. This allows developers to focus on building powerful applications that utilize real-time data without worrying about the complexities of managing data connections and APIs.&lt;br&gt;
With a few lines of SQL and a simple YAML configuration, you can build, deploy and maintain full data backends. It also has support for client libraries in JS and React to easily integrate with front-end applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Open Source?
&lt;/h2&gt;

&lt;p&gt;There are several reasons why we decided to make Dozer open source:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Community-driven innovation:&lt;/strong&gt; We want developers from all over the world to contribute their ideas,and provide valuable insights, improvements, and fixes, leading to a more innovative and robust platform, and faster development cycles.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Transparency and trust:&lt;/strong&gt; We want to enable users to view and understand the underlying code, fostering trust in the platform and ensuring that it meets their needs and expectations. Especially how data is being stored and processed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Collaboration and learning:&lt;/strong&gt; We encourage developers to collaborate, share ideas, and learn from one another. We want to foster a strong community that helps developers grow their skills and expertise in the real-time data space.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Getting Started with Dozer
&lt;/h2&gt;

&lt;p&gt;To help you get started with Dozer, we've created  &lt;a href="https://getdozer.io/docs/dozer/" rel="noopener noreferrer"&gt;documentation&lt;/a&gt; and &lt;a href="https://getdozer.io/blogs/" rel="noopener noreferrer"&gt;tutorial blogs&lt;/a&gt; that guide you through the process of setting up, configuring, and using Dozer for your data applications. You can find these resources on our official documentation site and can also follow &lt;a href="https://dev.to/getdozer"&gt;Dozer on dev.to&lt;/a&gt; or additional resources on getting to know &amp;amp; use Dozer better!&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Contribute?
&lt;/h2&gt;

&lt;p&gt;We welcome contributions from the community! If you're interested in contributing to Dozer, please check out our GitHub &lt;a href="https://github.com/getdozer/dozer" rel="noopener noreferrer"&gt;repository&lt;/a&gt; for the guidelines. Whether you want to submit a bug report, suggest a new feature, or contribute code, we appreciate your help in making Dozer even better.&lt;/p&gt;

&lt;p&gt;We also encourage you to check out the following resources to know other ways of contributions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Show and tell GitHub discussion forum&lt;/strong&gt;: We have setup a &lt;a href="https://github.com/getdozer/dozer/discussions/categories/show-and-tell" rel="noopener noreferrer"&gt;GitHub discussion forum&lt;/a&gt;, where you can share your Dozer projects, and experience, ask questions, do a feature request, and connect with fellow Dozer community members. Feel free to join the conversation and share your own projects &amp;amp; ideas!
Additionally, we have also created a discord channel to give developers an opportunity to showcase and talk about their projects. Join our &lt;a href="https://discord.gg/64rQR4d3Z8" rel="noopener noreferrer"&gt;discord channel&lt;/a&gt;, If you’ve built something using Dozer, we’d love to see it!&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dozer Samples Repository&lt;/strong&gt;: We have created a &lt;a href="https://github.com/getdozer/dozer-samples" rel="noopener noreferrer"&gt;Dozer Samples repository&lt;/a&gt; on GitHub, which contains sample applications built using Dozer. This repository can be a good resource for learning how to use Dozer and getting inspiration for your projects. You can also contribute to the dozer-sample repository by submitting a pull request with your projects. This not only helps showcase your work but also provides good examples for other developers to learn from and take inspiration to build their own projects.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can also join our community &lt;a href="https://discord.com/invite/3eWXBgJaEQ" rel="noopener noreferrer"&gt;discord&lt;/a&gt; to see what we are cooking at Dozer :female-cook: :male-cook:&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;We believe that by making Dozer open source, we are empowering the developer community to build amazing real-time data applications. We look forward to seeing the project and ideas that arise from this collaborative effort, and we're excited to work together to shape the future of real-time data!&lt;br&gt;
Together, we can shape the future of real-time data and contribute to the ongoing success of open source software. 🚀&lt;/p&gt;

&lt;p&gt;Happy coding, Happy Data APIng! 🚀👩‍💻👨‍💻&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>community</category>
      <category>database</category>
      <category>sql</category>
    </item>
    <item>
      <title>Building a Real-time Data App with Dozer, React, and PostgreSQL</title>
      <dc:creator>Abhishek Mishra</dc:creator>
      <pubDate>Wed, 19 Apr 2023 08:13:29 +0000</pubDate>
      <link>https://dev.to/getdozer/building-a-real-time-data-app-with-dozer-react-and-postgresql-391n</link>
      <guid>https://dev.to/getdozer/building-a-real-time-data-app-with-dozer-react-and-postgresql-391n</guid>
      <description>&lt;p&gt;In today's data-driven world, having access to real-time data is crucial and gaining a value from the data is more cumbersome. Another challenge developers face when working with real-time data is efficiently and quickly fetching, processing, and displaying the insights from the data.&lt;/p&gt;

&lt;p&gt;Enter &lt;a href="https://github.com/getdozer/dozer" rel="noopener noreferrer"&gt;Dozer&lt;/a&gt;, it simplifies the process of creating low-latency data APIs (gRPC and REST) from any data source easily with OpenAPI specification. Dozer is a real-time data engineering tool built with Rust, which enables seamless integration of data streams(sources), efficient data processing, and lightning-fast response times. This allows developers to focus on building applications without worrying about the complexity of managing real-time data.&lt;/p&gt;

&lt;p&gt;To know more about it's capabilities and features you can checkout Dozer &lt;a href="https://github.com/getdozer/dozer" rel="noopener noreferrer"&gt;repository&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In this blog, we'll walk you through the process of creating a real-time flight data application using Dozer, React.&lt;br&gt;
For this particular blog, we are using PostgreSQL as our data source, but it's important to note that there can be multiple data sources that can be connected to Dozer and subsequently used by your React application. By using Dozer, you can quickly create efficient data APIs that enable seamless integration with your frontend applications.&lt;br&gt;
PostgreSQL is connected to Dozer via &lt;a href="https://getdozer.io/docs/configuration/connectors#postgres" rel="noopener noreferrer"&gt;PostgreSQL connector&lt;/a&gt; and fetches data from multiple Postgres tables that has a flight data and combines them in real time based on the queries and produces fast READ APIs.&lt;/p&gt;



&lt;p&gt;On the client side, React app is being used to display the flight data on map coming from Dozer. The &lt;code&gt;dozerjs&lt;/code&gt; and &lt;code&gt;dozer-react&lt;/code&gt; libraries are used to make it easy to interact with Dozer and access real-time data without having to hardcode API endpoints in the code.&lt;br&gt;
The &lt;code&gt;dozerjs&lt;/code&gt; library manages gRPC requests between the frontend and the Dozer app, while the &lt;code&gt;dozer-react&lt;/code&gt; library provides React hooks for easy integration with React components.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz9evy1jday2fzwxfqfc9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz9evy1jday2fzwxfqfc9.png" alt="Building a Real-time Data App with Dozer, React, and PostgreSQL architecture diagram" width="800" height="226"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So let's dive in and learn how to harness the power of Dozer to create amazing real-time data-driven applications! 💪✨&lt;/p&gt;
&lt;h3&gt;
  
  
  🐘 Setting Up PostgreSQL:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Clone the sample repository and navigate to the appropriate directory:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/getdozer/dozer-samples.git
&lt;span class="nb"&gt;cd &lt;/span&gt;dozer-samples/usecases/pg-flights
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;Checkout the &lt;code&gt;react&lt;/code&gt; branch:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git checkout react
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;In the &lt;code&gt;usecases/pg-flights/&lt;/code&gt; directory, run the following command to start PostgreSQL using Docker Compose:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker-compose up
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This command will create a PostgreSQL container with the necessary configuration and sample flight data as shown below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffayj9qeks44l84eu96i4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffayj9qeks44l84eu96i4.png" alt="output log of postgresq running as a container with floght data sample" width="800" height="297"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To test the connection to the PostgreSQL container, you can use &lt;code&gt;psql&lt;/code&gt; or any PostgreSQL client. Here's an example using &lt;code&gt;psql&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;psql &lt;span class="nt"&gt;-h&lt;/span&gt; localhost &lt;span class="nt"&gt;-p&lt;/span&gt; 5437 &lt;span class="nt"&gt;-U&lt;/span&gt; postgres &lt;span class="nt"&gt;-d&lt;/span&gt; flights
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command connects to the flights database using the postgres user on the default port &lt;code&gt;5437&lt;/code&gt;. Once connected, you can run SQL queries to explore the sample flight data.&lt;/p&gt;

&lt;p&gt;With PostgreSQL set up and running, we can now proceed to build the React application and configure Dozer.&lt;/p&gt;

&lt;h3&gt;
  
  
  ⚛️ Building &amp;amp; Running the React App 🚀:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Open a new termincal and navigate to the &lt;code&gt;/usecases/react&lt;/code&gt; directory in the cloned dozer-samples repository:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;dozer-samples/usecases/react
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This directory contains a sample React app that displays flight data on a map component.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Install the required packages for the app using yarn install:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;In the project directory, run the following command to start the development server:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command runs the app in development mode.&lt;/p&gt;

&lt;p&gt;Open &lt;a href="http://localhost:3000" rel="noopener noreferrer"&gt;http://localhost:3000&lt;/a&gt; to view it in your browser. The page will automatically reload when you make changes, and you may also see any lint errors in the console. On this page, you will the Dozer logo, now navigate to &lt;a href="http://localhost:3000/airports" rel="noopener noreferrer"&gt;http://localhost:3000/airports&lt;/a&gt; to see the map UI for respective ariport and it's flight booking data as follow:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx8xk2155q94ejmv1pv6h.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx8xk2155q94ejmv1pv6h.jpg" alt="react app page with map component without live data" width="800" height="448"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This React app uses the &lt;a href="https://github.com/getdozer/dozer-js" rel="noopener noreferrer"&gt;@dozerjs/dozer&lt;/a&gt; and &lt;a href="https://github.com/getdozer/dozer-react" rel="noopener noreferrer"&gt;@dozerjs/dozer-react&lt;/a&gt; libraries to interact with Dozer, enabling seamless integration and real-time data updates.&lt;/p&gt;

&lt;p&gt;Since, we have not configured the Dozer with PostgreSQL yet, there is not data on the map.&lt;br&gt;
Let' quickly setup the Dozer and see the magic happening!&lt;/p&gt;


&lt;h3&gt;
  
  
  🔌 Configuring Dozer and PostgreSQL Connector:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Start by installing Dozer. In for this blog, we'll use Homebrew for the installation.
To learn about other installation methods, visit the official Dozer &lt;a href="https://getdozer.io/docs/installation" rel="noopener noreferrer"&gt;installation&lt;/a&gt; documentation.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;open a new terminal, ensuring you're in the same directory as your React project, and run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew tap getdozer/dozer
brew &lt;span class="nb"&gt;install &lt;/span&gt;dozer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Once the installation is complete, create a &lt;code&gt;dozer-config.yaml&lt;/code&gt; file in your project directory and paste the following configuration into it:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# dozer-config.yaml content&lt;/span&gt;

&lt;span class="na"&gt;app_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;flight-microservices&lt;/span&gt;
&lt;span class="na"&gt;connections&lt;/span&gt;&lt;span class="pi"&gt;:&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;flights_conn&lt;/span&gt;
    &lt;span class="na"&gt;config&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!Postgres&lt;/span&gt;
      &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres&lt;/span&gt;
      &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres&lt;/span&gt;
      &lt;span class="na"&gt;host&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;0.0.0.0&lt;/span&gt;
      &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5437&lt;/span&gt;
      &lt;span class="na"&gt;database&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;flights&lt;/span&gt;

&lt;span class="na"&gt;sql&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
  &lt;span class="s"&gt;select f.arrival_airport as airport, a.coordinates as coordinates, COUNT(t.ticket_no) as tickets&lt;/span&gt;
  &lt;span class="s"&gt;INTO airports_count&lt;/span&gt;
  &lt;span class="s"&gt;from tickets t&lt;/span&gt;
  &lt;span class="s"&gt;join ticket_flights tf on t.ticket_no = tf.ticket_no&lt;/span&gt;
  &lt;span class="s"&gt;join flights f on tf.flight_id = f.flight_id&lt;/span&gt;
  &lt;span class="s"&gt;join airports a on f.arrival_airport = a.airport_code&lt;/span&gt;
  &lt;span class="s"&gt;group by f.arrival_airport, a.coordinates;&lt;/span&gt;

  &lt;span class="s"&gt;select extract(HOUR FROM f.window_start) as start, count(f.window_start) as dep_count&lt;/span&gt;
  &lt;span class="s"&gt;INTO departures_count&lt;/span&gt;
  &lt;span class="s"&gt;from TUMBLE(flights, scheduled_departure, '4 HOURS') f&lt;/span&gt;
  &lt;span class="s"&gt;group by extract(HOUR FROM f.window_start)&lt;/span&gt;

&lt;span class="na"&gt;sources&lt;/span&gt;&lt;span class="pi"&gt;:&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;tickets&lt;/span&gt;
    &lt;span class="na"&gt;table_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;tickets&lt;/span&gt;
    &lt;span class="na"&gt;columns&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;connection&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!Ref&lt;/span&gt; &lt;span class="s"&gt;flights_conn&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;flights&lt;/span&gt;
    &lt;span class="na"&gt;table_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;flights&lt;/span&gt;
    &lt;span class="na"&gt;columns&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;connection&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!Ref&lt;/span&gt; &lt;span class="s"&gt;flights_conn&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;ticket_flights&lt;/span&gt;
    &lt;span class="na"&gt;table_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ticket_flights&lt;/span&gt;
    &lt;span class="na"&gt;columns&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;connection&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!Ref&lt;/span&gt; &lt;span class="s"&gt;flights_conn&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;airports&lt;/span&gt;
    &lt;span class="na"&gt;table_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;airports&lt;/span&gt;
    &lt;span class="na"&gt;columns&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;connection&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!Ref&lt;/span&gt; &lt;span class="s"&gt;flights_conn&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;airports_flights_schema&lt;/span&gt;
    &lt;span class="na"&gt;table_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;airports&lt;/span&gt;
    &lt;span class="na"&gt;columns&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;schema&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;flights_schema&lt;/span&gt;
    &lt;span class="na"&gt;connection&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!Ref&lt;/span&gt; &lt;span class="s"&gt;flights_conn&lt;/span&gt;

&lt;span class="na"&gt;endpoints&lt;/span&gt;&lt;span class="pi"&gt;:&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;tickets&lt;/span&gt;
    &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/bookings/tickets&lt;/span&gt;
    &lt;span class="na"&gt;table_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;tickets&lt;/span&gt;
    &lt;span class="na"&gt;index&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;primary_key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;ticket_no&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;flights&lt;/span&gt;
    &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/bookings/flights&lt;/span&gt;
    &lt;span class="na"&gt;table_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;flights&lt;/span&gt;
    &lt;span class="na"&gt;index&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;primary_key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;flight_id&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;airports&lt;/span&gt;
    &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/bookings/airports&lt;/span&gt;
    &lt;span class="na"&gt;table_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;airports&lt;/span&gt;
    &lt;span class="na"&gt;index&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;primary_key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;airport_code&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;ticket_flights&lt;/span&gt;
    &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/bookings/ticket_flights&lt;/span&gt;
    &lt;span class="na"&gt;table_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ticket_flights&lt;/span&gt;
    &lt;span class="na"&gt;index&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;primary_key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;ticket_no&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;flight_id&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;airports_count&lt;/span&gt;
    &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/airports_count&lt;/span&gt;
    &lt;span class="na"&gt;table_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;airports_count&lt;/span&gt;
    &lt;span class="na"&gt;index&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;primary_key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;airport&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;coordinates&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;departures_count&lt;/span&gt;
    &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/departures_count&lt;/span&gt;
    &lt;span class="na"&gt;table_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;departures_count&lt;/span&gt;
    &lt;span class="na"&gt;index&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;primary_key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;start&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This configuration defines the PostgreSQL connector and sets up the API endpoints that our React application will use to fetch data.&lt;br&gt;
For more information about the PostgreSQL connector, refer to &lt;a href="https://getdozer.io/docs/configuration/connectors#postgres" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;.&lt;br&gt;
Dozer supports multiple connectors, allowing you to integrate various data sources. Check out the list of available connectors for more &lt;a href="https://getdozer.io/docs/configuration/connectors" rel="noopener noreferrer"&gt;options&lt;/a&gt;.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;With the configuration in place, run Dozer in action by executing the following command:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dozer -c dozer-config.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, you should see Dozer logs indicating that the endpoints is ready to be queried by the React app.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiilzitpj55j4vxe5ayk1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiilzitpj55j4vxe5ayk1.png" alt="dozer logs after starting dozer" width="800" height="717"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can now access your application at &lt;a href="http://localhost:3000/airports" rel="noopener noreferrer"&gt;http://localhost:3000/airports&lt;/a&gt; to see the real-time flight data populating on the map component as shown below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu3b9no21mxs9jfbknpgg.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu3b9no21mxs9jfbknpgg.gif" alt="react app page with map component with live flight data" width="600" height="376"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Additionally, You can also query the API using gRPC and REST endpoints to test the data. In this case, you can use the REST endpoint using &lt;a href="https://curl.se/" rel="noopener noreferrer"&gt;curl&lt;/a&gt; or &lt;a href="https://www.postman.com/download" rel="noopener noreferrer"&gt;Postman&lt;/a&gt; &lt;a href="http://localhost:8080/airports/" rel="noopener noreferrer"&gt;http://localhost:8080/airports/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F80y4imltueuw10msvdof.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F80y4imltueuw10msvdof.png" alt="OpenAPI specification for dozer genrated endpoint" width="800" height="850"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Additionally, you can check the OpenAPI specification documentation that Dozer generates for endpoints by requesting &lt;code&gt;http://localhost:&amp;lt;port&amp;gt;/&amp;lt;endpoint_path&amp;gt;/oapi&lt;/code&gt; as shown below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0ijdompgvqxsftfniy5m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0ijdompgvqxsftfniy5m.png" alt="OpenAPI documentation of ednpoints generated by dozer" width="800" height="888"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  🌟  Conclusion:
&lt;/h3&gt;

&lt;p&gt;Congratulations! You've successfully built a real-time flight data app using Dozer, React, and PostgreSQL. This powerful combination enables you to create interactive and data-driven applications with ease.&lt;br&gt;
Feel free to expand on this example and explore other data sources and connectors to enhance your app's capabilities. Enjoy exploring the application and customizing it further to suit your needs!&lt;/p&gt;

&lt;p&gt;Happy coding, Happy Data APIng! 🚀👩‍💻👨‍💻&lt;/p&gt;

</description>
      <category>react</category>
      <category>postgres</category>
      <category>api</category>
      <category>systems</category>
    </item>
    <item>
      <title>This week at Dozer #5</title>
      <dc:creator>Abhishek Mishra</dc:creator>
      <pubDate>Tue, 18 Apr 2023 04:43:51 +0000</pubDate>
      <link>https://dev.to/getdozer/this-week-at-dozer-5-49ha</link>
      <guid>https://dev.to/getdozer/this-week-at-dozer-5-49ha</guid>
      <description>&lt;p&gt;🌟 Welcome to this week's update on dozer! Dozer is excited to announce the release of version v0.1.17, which brings a host of new features and improvements. Our team has been working tirelessly to enhance the overall functionality, and we can't wait for you to experience all the new features. Here are the updates for this week.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key enhancement of v0.1.17 🚀
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Switched to Apache License &lt;a href="https://github.com/getdozer/dozer/pull/1404" rel="noopener noreferrer"&gt;#1404&lt;/a&gt; 📜:
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;In this release, Dozer has switched to the Apache License (The 2.0 version), making is 100% Open Source. This change provides a more permissive and flexible licensing option, encouraging collaboration and adoption by a wider range of developers and organizations.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Asyncify Connectors &lt;a href="https://github.com/getdozer/dozer/pull/1409" rel="noopener noreferrer"&gt;#1409&lt;/a&gt; ⚡:
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;In this release, connectors have been refactored to work asynchronously, leading to performance improvements and smoother execution.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  SQL Logic Test Framework &lt;a href="https://github.com/getdozer/dozer/pull/1326" rel="noopener noreferrer"&gt;#1326&lt;/a&gt; 🧪:
&lt;/h3&gt;

&lt;p&gt;A new SQL Logic Test Framework has been introduced, allowing for more comprehensive testing of Dozer's SQL capabilities.&lt;/p&gt;

&lt;h3&gt;
  
  
  APIs for Monitoring and Status Updates &lt;a href="https://github.com/getdozer/dozer/pull/1329" rel="noopener noreferrer"&gt;#1329&lt;/a&gt; 📈:
&lt;/h3&gt;

&lt;p&gt;We've added APIs for monitoring and status updates, enabling better insight into Dozer's performance and health.&lt;/p&gt;

&lt;h3&gt;
  
  
  Graceful API Thread Shutdown &lt;a href="https://github.com/getdozer/dozer/pull/1416" rel="noopener noreferrer"&gt;#1416&lt;/a&gt; 🛠️:
&lt;/h3&gt;

&lt;p&gt;The API thread now shuts down gracefully, preventing potential issues with abrupt termination.&lt;/p&gt;

&lt;h3&gt;
  
  
  Dozer Lambda Functions: A Glimpse into the Future 🚀🔮 &lt;a href="https://github.com/getdozer/dozer/pull/1424" rel="noopener noreferrer"&gt;#1424&lt;/a&gt;, &lt;a href="https://github.com/getdozer/dozer/pull/1424" rel="noopener noreferrer"&gt;#1426&lt;/a&gt; 🐍🌐:
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;We're excited to share that we've released JavaScript and Python bindings for reading Dozer logs. These bindings will be part of our Dozer Lambda runtime, allowing you to create Lambda functions in JS and Python that react to Dozer events. Just imagine triggering a Twilio notification based on a SQL statement (data change condition)! This feature is currently experimental, and we'll publish a complete article with use cases and samples soon.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5jh34ullovt53iun1pnx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5jh34ullovt53iun1pnx.png" alt="state diagram of dozer lambda runtime on data change condition" width="778" height="307"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: DCC stands for Data Change Condition&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Here's an example for JavaScript:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dozer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;..&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;runtime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;dozer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Runtime&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;reader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;runtime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_reader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../.dozer/pipeline&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;trips&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;op&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;next_op&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;op&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;And for Python:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;dozer_log&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;reader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;dozer_log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LogReader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;../.dozer/pipeline&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;trips&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;next_op&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;asyncio&lt;/span&gt;
    &lt;span class="n"&gt;asyncio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In these examples, the &lt;code&gt;console.log()&lt;/code&gt; and &lt;code&gt;print()&lt;/code&gt; statements can be replaced with user-defined code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Other Improvements &amp;amp; Fixes 🔧
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Fixed e2e tests writing to directories that are not removed in &lt;a href="https://github.com/getdozer/dozer/pull/1407" rel="noopener noreferrer"&gt;#1407&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Fixed type validation in &lt;a href="https://github.com/getdozer/dozer/pull/1405" rel="noopener noreferrer"&gt;#1405&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Replaced &lt;code&gt;std::thread::sleep&lt;/code&gt; with &lt;code&gt;tokio::time::sleep&lt;/code&gt; in &lt;a href="https://github.com/getdozer/dozer/pull/1413" rel="noopener noreferrer"&gt;#1413&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Consolidated to a single Tokio runtime for everything in &lt;a href="https://github.com/getdozer/dozer/pull/1417" rel="noopener noreferrer"&gt;#1417&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Used the correct runtime for internal pipeline thread in &lt;a href="https://github.com/getdozer/dozer/pull/1418" rel="noopener noreferrer"&gt;#1418&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Refactored as dozer-log crate in &lt;a href="https://github.com/getdozer/dozer/pull/1420" rel="noopener noreferrer"&gt;#1420&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Used proper error message for PostgreSQL replication slot creation in &lt;a href="https://github.com/getdozer/dozer/pull/1422" rel="noopener noreferrer"&gt;#1422&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Stored schema of sinks separately in &lt;a href="https://github.com/getdozer/dozer/pull/1423" rel="noopener noreferrer"&gt;#1423&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Added deb generation to release process in &lt;a href="https://github.com/getdozer/dozer/pull/1432" rel="noopener noreferrer"&gt;#1432&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Removed unnecessary &lt;code&gt;workspace.exclude&lt;/code&gt; in &lt;code&gt;Cargo.toml&lt;/code&gt; in &lt;a href="https://github.com/getdozer/dozer/pull/1430" rel="noopener noreferrer"&gt;#1430&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Bumped h2 from &lt;code&gt;0.3.16&lt;/code&gt; to &lt;code&gt;0.3.17&lt;/code&gt; in &lt;a href="https://github.com/getdozer/dozer/pull/1427" rel="noopener noreferrer"&gt;#1427&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Dozer v0.1.17 is available now. Check out the release notes &lt;a href="https://github.com/getdozer/dozer/releases/tag/v0.1.17" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Looking Forward 🌈&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As we continue to make strides in improving Dozer, we remain committed to enhancing its features and functionality. Your feedback is invaluable to us, so please don't hesitate to reach out with any suggestions or ideas. Together, we can make Dozer the best it can be!&lt;/p&gt;

&lt;h3&gt;
  
  
  Full Changelog:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/getdozer/dozer/compare/v0.1.16...v0.1.17" rel="noopener noreferrer"&gt;v0.1.16...v0.1.17&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Contact us 📬
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/getdozer/dozer" rel="noopener noreferrer"&gt;https://github.com/getdozer/dozer&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Discord: &lt;a href="https://discord.com/invite/3eWXBgJaEQ" rel="noopener noreferrer"&gt;https://discord.com/invite/3eWXBgJaEQ&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Twitter: &lt;a href="https://twitter.com/GetDozer" rel="noopener noreferrer"&gt;https://twitter.com/GetDozer&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;LinkedIn: &lt;a href="https://www.linkedin.com/company/getdozer/" rel="noopener noreferrer"&gt;https://www.linkedin.com/company/getdozer/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>rust</category>
      <category>opensource</category>
      <category>database</category>
      <category>api</category>
    </item>
    <item>
      <title>Celebrating Dozer v0.1.16 Release and Exiting Stealth Mode 🎉</title>
      <dc:creator>Abhishek Mishra</dc:creator>
      <pubDate>Wed, 12 Apr 2023 05:12:30 +0000</pubDate>
      <link>https://dev.to/getdozer/celebrating-dozer-v0116-release-and-exiting-stealth-mode-37gl</link>
      <guid>https://dev.to/getdozer/celebrating-dozer-v0116-release-and-exiting-stealth-mode-37gl</guid>
      <description>&lt;p&gt;Dozer is a powerful, plug-and-play data infrastructure back end designed to help developers build real-time,low-latency data APIs (gRPC and REST) from any data source data apps quickly and efficiently. Dozer streamlines the process of accessing and managing real-time data updates. Key features include support for various data types, optimized join indexes structure, high-performance cache and seamless authorization implementation for gRPC/REST methods.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Features:
&lt;/h2&gt;

&lt;p&gt;Here is a summary of all key features released till date.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Open Source&lt;/strong&gt;: Dozer has transitioned to a fully open-source model and adopted the Apache 2.0 license. We value the contributions and input from our community.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Built with Rust&lt;/strong&gt;: We care about performance a lot and Dozer is built end to end in Rust&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Client Libraries&lt;/strong&gt;: Dozer has libraries in &lt;a href="https://www.npmjs.com/package/@dozerjs/dozer?activeTab=readme" rel="noopener noreferrer"&gt;JS&lt;/a&gt;, &lt;a href="https://www.npmjs.com/package/@dozerjs/dozer-react" rel="noopener noreferrer"&gt;React&lt;/a&gt; and &lt;a href="https://pypi.org/project/pydozer/" rel="noopener noreferrer"&gt;Python&lt;/a&gt; for easy integration.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Reactive SQL Engine&lt;/strong&gt;: Dozer stays in sync by transforming data in real-time, providing a real time view of your data.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Out of the box Data APIs with Protobuf and OpenAPI support&lt;/strong&gt;: Dozer automatically generates Open API documentation for REST and protobuf definitions for gRPC.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Caching Layer&lt;/strong&gt;: Dozer stores data in an embedded cache and automatically optimses for efficient queries and is horizontally scalable.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Wide Variety of Connectors&lt;/strong&gt;: Dozer connects with databases such as Postgres and MySQL, data warehouses such as Snowflake, data lakes and even the Ethereum ledger.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here is a short video of Dozer in action.&lt;/p&gt;

&lt;h2&gt;
  
  
  We are Trending on Github 🥳 :
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwsh18gv9plfh8k5mqyv7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwsh18gv9plfh8k5mqyv7.png" alt="dozer trending on github" width="800" height="604"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  We got featured on TechCrunch 🥳 :
&lt;/h2&gt;

&lt;p&gt;We were recently featured in &lt;strong&gt;TechCrunch&lt;/strong&gt; with the title &lt;a href="https://techcrunch.com/2023/04/03/dozer-exits-stealth-to-help-any-developer-build-real-time-data-apps-in-minutes/" rel="noopener noreferrer"&gt;"Dozer exits stealth to help any developer build real-time data apps 'in minutes'"&lt;/a&gt;. The article highlights how Dozer is addressing the challenges of stream data processing, by powering fast, read-only APIs directly from any source via a plug-and-play data infrastructure back end.&lt;/p&gt;

&lt;p&gt;Founded by &lt;a href="https://www.linkedin.com/in/vivekaditya/" rel="noopener noreferrer"&gt;Vivek Gudapuri&lt;/a&gt; and &lt;a href="https://www.linkedin.com/in/matteopelati/" rel="noopener noreferrer"&gt;Matteo Pelati&lt;/a&gt;, Dozer has been in testing with select design partners and has now emerged from stealth for any developer to access. The company also revealed it has raised $3 million in seed funding from Sequoia Capital's Indian arm (via its Surge program), Google's Gradient Ventures, and January Capital.&lt;/p&gt;

&lt;p&gt;Dozer's unique approach provides developers with an efficient way to access real-time data updates and APIs within a single product. As a result, developers can save time and money by avoiding the need to build and maintain multiple integrations.&lt;/p&gt;

&lt;p&gt;We are extremely proud of our achievements and grateful for the support of our investors and design partners. As we continue to grow, we remain committed to delivering the best possible experience for developers and helping them build real-time data apps quickly and efficiently.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Read the full TechCrunch article &lt;a href="https://techcrunch.com/2023/04/03/dozer-exits-stealth-to-help-any-developer-build-real-time-data-apps-in-minutes/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Community achievements &amp;amp; other citations:
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Exciting News: Dozer is now fully open source!&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Based on community feedback, Dozer has transitioned to a fully open-source model and adopted the Apache 2.0 license. We value the contributions and input from our community, and we look forward to continuing to grow and evolve together. Stay tuned for a detailed blog post on this topic in the coming week.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Our Reddit Community:&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;We are delighted to see the love and support from our community on Reddit. The enthusiasm and engagement from developers and users have been invaluable in shaping the future of Dozer. Check out the Reddit thread here: &lt;a href="https://www.reddit.com/r/rust/comments/12hb818/dozer_a_scalable_realtime_data_apis_backend/" rel="noopener noreferrer"&gt;https://www.reddit.com/r/rust/comments/12hb818/dozer_a_scalable_realtime_data_apis_backend/&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Key Enhancements of v0.1.16:
&lt;/h2&gt;

&lt;p&gt;Welcome to this week's update on Dozer! We are excited to announce the release of version &lt;code&gt;v0.1.16&lt;/code&gt;, which brings a host of new features and improvements. Alongside this update, we are thrilled to share our recent feature in TechCrunch, announcing that Dozer has exited stealth mode!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Fixes and Documentation:&lt;/strong&gt;&lt;br&gt;
    We have fixed the README Ubuntu instructions, ensuring a smoother user experience for Ubuntu users. Additionally, we've implemented integration tests on the Github runner, improving the stability and reliability of our codebase.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Performance Improvements:&lt;/strong&gt;&lt;br&gt;
    Our team has been hard at work optimizing performance, including using &lt;code&gt;MDB_APPEND&lt;/code&gt; when possible and reading object store files in parallel. These enhancements contribute to a more efficient and faster user experience.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Feature Additions:&lt;/strong&gt;&lt;br&gt;
    We have implemented several new features, such as authorization in gRPC methods, support for u128 and i128 &lt;code&gt;Field&lt;/code&gt; and &lt;code&gt;FieldType&lt;/code&gt;, and snapshotting started messages in the ingestion process. These features will provide more functionality and improve the overall user experience.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Code Refactoring and Optimization:&lt;/strong&gt;&lt;br&gt;
    Our team has been focusing on optimizing code, including refactoring the Join indexes structure and removing &lt;code&gt;Record::version&lt;/code&gt;. This will contribute to a more robust and easier-to-manage codebase.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Duration Field and Aggregation Support:&lt;/strong&gt;&lt;br&gt;
    We have added &lt;code&gt;Duration&lt;/code&gt;, &lt;code&gt;Field&lt;/code&gt; &amp;amp; &lt;code&gt;FieldType&lt;/code&gt; support, as well as Duration for SQL representation and aggregation support. These additions will provide users with more flexibility when working with time-based data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. Bug Fixes:&lt;/strong&gt;&lt;br&gt;
    We have addressed several issues, such as fixing minor errors while running with duration, updating resolution atomicity and stream operations, and resolving gRPC errors caused by duration. These bug fixes will contribute to a more stable and reliable product.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Read the full release notes &lt;a href="https://github.com/getdozer/dozer/releases/tag/v0.1.16" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Other Citations and Press Releases:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Yahoo News Singapore: "Dozer exits stealth to help any developer build real-time data apps ‘in minutes’" - &lt;a href="https://sg.news.yahoo.com/dozer-exits-stealth-help-developer-060042513.html" rel="noopener noreferrer"&gt;https://sg.news.yahoo.com/dozer-exits-stealth-help-developer-060042513.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Surge leads $3m round of SG API firm - &lt;a href="https://www.techinasia.com/surge-leads-3m-round-of-sg-api-firm" rel="noopener noreferrer"&gt;https://www.techinasia.com/surge-leads-3m-round-of-sg-api-firm&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Singapore's Dozer raises $3M funding led by Sequoia Capital India and Southeast Asia’s Surge - &lt;a href="https://technode.global/2023/04/04/singapores-dozer-raises-3m-funding-led-by-sequoia-capital-india-and-southeast-asias-surge/" rel="noopener noreferrer"&gt;https://technode.global/2023/04/04/singapores-dozer-raises-3m-funding-led-by-sequoia-capital-india-and-southeast-asias-surge/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Sequoia Capital, Others Invest $3 M In Dozer's Seed Round - &lt;a href="https://bwdisrupt.businessworld.in/article/Sequoia-Capital-Others-Invest-3-M-In-Dozer-s-Seed-Round/04-04-2023-471607/" rel="noopener noreferrer"&gt;https://bwdisrupt.businessworld.in/article/Sequoia-Capital-Others-Invest-3-M-In-Dozer-s-Seed-Round/04-04-2023-471607/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Dozer raises $3 Mn led by Sequoia Capital India and Surge - &lt;a href="https://entrackr.com/2023/04/dozer-raises-3-mn-led-by-sequoia-capital-india-and-surge/" rel="noopener noreferrer"&gt;https://entrackr.com/2023/04/dozer-raises-3-mn-led-by-sequoia-capital-india-and-surge/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Early-Stage Startups Prozeal Infra, Zyod, Others Raise Funding - &lt;a href="https://www.vccircle.com/earlystage-startups-prozeal-infra-zyod-others-raise-funding" rel="noopener noreferrer"&gt;https://www.vccircle.com/earlystage-startups-prozeal-infra-zyod-others-raise-funding&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Dozer raises $3 million in funding, emerges from stealth mode - &lt;a href="https://economictimes.indiatimes.com/tech/funding/dozer-raises-3-million-in-funding-emerges-from-stealth-mode/articleshow/99237814.cms" rel="noopener noreferrer"&gt;https://economictimes.indiatimes.com/tech/funding/dozer-raises-3-million-in-funding-emerges-from-stealth-mode/articleshow/99237814.cms&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Dozer Raises $3 Million In Seed Funding - &lt;a href="https://www.entrepreneur.com/en-in/news-and-trends/dozer-raises-3-million-in-seed-funding/448966" rel="noopener noreferrer"&gt;https://www.entrepreneur.com/en-in/news-and-trends/dozer-raises-3-million-in-seed-funding/448966&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Dozer raises US$3M to help engineers instantly build real-time data APIs - &lt;a href="https://www.cxotoday.com/press-release/dozer-raises-us3m-to-help-engineers-instantly-build-real-time-data-apis/" rel="noopener noreferrer"&gt;https://www.cxotoday.com/press-release/dozer-raises-us3m-to-help-engineers-instantly-build-real-time-data-apis/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;B2B apparel startup Zyod, tech startup Dozer raise funding - &lt;a href="https://www.zeebiz.com/startups/news-b2b-apparel-startup-zyod-tech-startup-dozer-raise-funding-229028" rel="noopener noreferrer"&gt;https://www.zeebiz.com/startups/news-b2b-apparel-startup-zyod-tech-startup-dozer-raise-funding-229028&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Data infrastructure platform Dozer raises $3 million in seed funding - &lt;a href="https://www.thehindubusinessline.com/info-tech/data-infrastructure-platform-dozer-raises-3-million-in-seed-funding/article66698503.ece" rel="noopener noreferrer"&gt;https://www.thehindubusinessline.com/info-tech/data-infrastructure-platform-dozer-raises-3-million-in-seed-funding/article66698503.ece&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Spendflo, Dozee, Blacksoil, and others raise funds - &lt;a href="https://yourstory.com/2023/04/blacksoil-spendflo-dozee-and-others-raise-funds" rel="noopener noreferrer"&gt;https://yourstory.com/2023/04/blacksoil-spendflo-dozee-and-others-raise-funds&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Dozer Secures US$ 3M in Seed Funding - &lt;a href="https://digitalterminal.in/startup/dozer-secures-us-3m-in-seed-funding" rel="noopener noreferrer"&gt;https://digitalterminal.in/startup/dozer-secures-us-3m-in-seed-funding&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Join us in celebrating these milestones as we continue to work towards our mission of empowering developers to build real-time data applications with ease and efficiency!&lt;/p&gt;

&lt;p&gt;Stay tuned for more updates, and join our community on &lt;a href="https://github.com/getdozer/doze" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;, &lt;a href="https://discord.com/invite/3eWXBgJaEQ" rel="noopener noreferrer"&gt;Discord&lt;/a&gt;, &lt;a href="https://twitter.com/GetDozer" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;, and &lt;a href="https://www.linkedin.com/company/getdozer/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Changelog
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/getdozer/dozer/compare/v0.1.15...v0.1.16" rel="noopener noreferrer"&gt;https://github.com/getdozer/dozer/compare/v0.1.15...v0.1.16&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Contact us
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/getdozer/dozer" rel="noopener noreferrer"&gt;https://github.com/getdozer/dozer&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Discord: &lt;a href="https://discord.com/invite/3eWXBgJaEQ" rel="noopener noreferrer"&gt;https://discord.com/invite/3eWXBgJaEQ&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Twitter: &lt;a href="https://twitter.com/GetDozer" rel="noopener noreferrer"&gt;https://twitter.com/GetDozer&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;LinkedIn: &lt;a href="https://www.linkedin.com/company/getdozer/" rel="noopener noreferrer"&gt;https://www.linkedin.com/company/getdozer/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>rust</category>
      <category>opensource</category>
      <category>data</category>
      <category>api</category>
    </item>
  </channel>
</rss>
