Featured image of post Using Protobuf Protocol Data in HTTP Requests

Using Protobuf Protocol Data in HTTP Requests

While protobuf is commonly used in RPC communications, there are scenarios where we also utilize it in HTTP requests

Recently I’ve been busy integrating third-party advertising platforms. During this process, I noticed that some API documentation was simply provided as Word documents with hundreds of parameters listed in tables, requiring manual parameter construction - a truly tedious process.

However, several providers stood out by offering .proto files, allowing automatic generation of Request and Response structures through protobuf - a developer-friendly approach worth applauding!

Key Takeaways

  • When integrating APIs, always ask business partners if protobuf schema files are available
    • Generate Go code using: protoc pb\xxx.proto --go_out=.
    • This automatically creates ready-to-use request/response structures, enums, etc., significantly streamlining backend integration (a pattern worth adopting for future backend interfaces)

Sample Implementation

package main

import (
	"bytes"
	"io/ioutil"
	"log"
	"net/http"

	"github.com/golang/protobuf/proto"
	"xxxx/internal/pb"
)

func main() {
	getDataByAdServe()
}

func getDataByAdServe() {
    // Serialize request data
    r := &pb.AdProfRequest{}
    data, er := proto.Marshal(r)
    if er != nil {
        log.Fatal(er)
        return
    }
    
    // Send HTTP request (set proper timeout in production)
    reader := bytes.NewReader(data)
    resp, err := http.Post("http://127.0.0.1:8001/xxx", "application/x-protobuf", reader)
    if err != nil {
        log.Println(err)
        return
    }
    defer resp.Body.Close()
    
    // Read response
    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        log.Println(err)
        return
    }
    
    // Deserialize response
    var res pb.AdProfResponse
    if err := proto.Unmarshal(body, &res); err != nil {
        log.Println(err)
        return
    }
    
    log.Println(&res)
}

This implementation demonstrates:

  1. Protobuf serialization/deserialization
  2. HTTP communication with protobuf payloads
  3. Proper error handling and resource cleanup

The application/x-protobuf Content-Type header ensures servers correctly interpret the binary payload. For production use, consider adding request timeouts and retry mechanisms.