If your target system can't connect directly to your database and only accepts data through HTTP APIs, Apache SeaTunnel has you covered.
In this tutorial, you'll learn how to build a real-time data pipeline that captures MySQL changes and pushes them directly to a web application's HTTP endpoint—no custom synchronization service required.
Prerequisites
Install the Required Connectors
Edit the config/plugin_config file and add the following connectors:
connector-http-base
connector-cdc-mysql
Then install the plugins:
sh bin/install-plugin.sh
Tip: If your network environment prevents automatic downloads, you can manually download the corresponding connector JARs from Maven Central and place them in the
connectors/directory.
Add the MySQL JDBC Driver
Copy mysql-connector-java-8.0.28.jar (or any compatible 8.x version) into the SeaTunnel lib/ directory.
Configure MySQL for CDC
SeaTunnel's MySQL CDC connector reads data from the MySQL binary log (Binlog), so Binlog must be enabled before you begin.
Open your MySQL configuration file (my.cnf or my.ini), add the following settings, and restart MySQL:
[mysqld]
server-id = 1
log-bin = mysql-bin
binlog-format = ROW
Configuration details:
-
server-id: Must be unique within the replication cluster. -
log-bin: Enables MySQL binary logging. -
binlog-format=ROW: Required for CDC to capture row-level changes accurately.
Build a Simple HTTP Receiver
Next, let's create a lightweight HTTP service to receive data from SeaTunnel.
Create a file named server.go:
package main
import (
"fmt"
"io"
"log"
"net/http"
)
// Handle all HTTP requests and print the received payload
func handler(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
body, err := io.ReadAll(r.Body)
if err != nil {
msg := fmt.Sprintf("Failed to read request body: %v", err)
http.Error(w, msg, http.StatusInternalServerError)
fmt.Println(msg)
return
}
if len(body) > 0 {
fmt.Printf("Request Body: %s\n", string(body))
fmt.Printf("Payload Size: %d bytes\n", len(body))
} else {
fmt.Println("Empty request body")
}
w.WriteHeader(http.StatusOK)
fmt.Fprintf(w, "Data received successfully. Payload size: %d bytes.", len(body))
}
func main() {
http.HandleFunc("/", handler)
fmt.Println("HTTP server started on port 9090...")
fmt.Println(`Test with: curl -X POST -d '{"test":123}' http://localhost:9090/`)
if err := http.ListenAndServe(":9090", nil); err != nil {
log.Fatal("Failed to start server: ", err)
}
}
Start the service:
go run server.go
Once you see "HTTP server started on port 9090...", your API endpoint is ready to receive data.
Prepare Test Data
Create a sample table in MySQL and insert two initial records:
CREATE TABLE `post` (
`id` int(11) NOT NULL,
`content` varchar(50) DEFAULT NULL,
`author` varchar(50) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
INSERT INTO `post` VALUES (1, 'Getting Started with MySQL', 'Alice');
INSERT INTO `post` VALUES (2, 'Understanding HTTP', 'Bob');
Create the SeaTunnel Job
Create a file named mysqlcdc_http.conf under the job/ directory.
env {
parallelism = 1
job.mode = "STREAMING"
checkpoint.interval = 10000
}
source {
MySQL-CDC {
username = "root"
password = "root"
table-names = [
"your_database.post"
]
url = "jdbc:mysql://your-mysql-host:3306/your_database"
schema-changes.enabled = true
}
}
sink {
Http {
url = "http://your-http-server:9090/"
headers {
Accept = "application/json"
Content-Type = "application/json;charset=utf-8"
}
}
}
Before running the job, replace the following with your own environment:
- MySQL hostname
- Database name
- Username and password
- HTTP endpoint URL
Start the Streaming Job
From the SeaTunnel installation directory, run:
bin/seatunnel.sh --config job/mysqlcdc_http.conf -m local
SeaTunnel will start capturing MySQL changes and stream them to your HTTP service in real time.
Verify Real-Time Synchronization
After the job starts successfully, you'll immediately see the two existing records being pushed to your HTTP service:
Starting HTTP server on port 9090...
Request Body:
{"id":1,"content":"Getting Started with MySQL","author":"Alice"}
Payload Size: 62 bytes
Request Body:
{"id":2,"content":"Understanding HTTP","author":"Bob"}
Payload Size: 56 bytes
SeaTunnel first performs an initial snapshot, so existing records are synchronized automatically.
Now insert a new record into MySQL:
INSERT INTO `post`
VALUES (3, 'Real-Time Sync with SeaTunnel', 'Charlie');
The HTTP service immediately receives the new data:
Request Body:
{"id":3,"content":"Real-Time Sync with SeaTunnel","author":"Charlie"}
Payload Size: 69 bytes
This confirms that incremental changes are being captured and delivered to your HTTP endpoint in real time.
Conclusion
With Apache SeaTunnel, building a real-time MySQL-to-HTTP data pipeline is straightforward.
Instead of granting downstream systems direct database access, you can stream data securely through standard HTTP APIs. This architecture is especially useful for:
- Integrating with third-party SaaS platforms
- Connecting internal business systems across departments
- Feeding custom web services or microservices
- Building event-driven applications
- Decoupling data producers from downstream consumers
Whether you're integrating legacy systems, modern web services, or external business platforms, SeaTunnel's CDC and HTTP connectors provide a flexible, scalable, and production-ready solution for real-time data delivery.

Top comments (0)