<?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: Pires Aurélio</title>
    <description>The latest articles on DEV Community by Pires Aurélio (@aureliopires186).</description>
    <link>https://dev.to/aureliopires186</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4139026%2Fb3901449-de70-40f3-9ea3-20ae359ce56c.jpg</url>
      <title>DEV Community: Pires Aurélio</title>
      <link>https://dev.to/aureliopires186</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/aureliopires186"/>
    <language>en</language>
    <item>
      <title>I Added Prometheus to My Go Job Scraper and It Changed How I Think About Production</title>
      <dc:creator>Pires Aurélio</dc:creator>
      <pubDate>Sat, 03 Oct 2026 23:27:21 +0000</pubDate>
      <link>https://dev.to/aureliopires186/i-added-prometheus-to-my-go-job-scraper-and-it-changed-how-i-think-about-production-3fhm</link>
      <guid>https://dev.to/aureliopires186/i-added-prometheus-to-my-go-job-scraper-and-it-changed-how-i-think-about-production-3fhm</guid>
      <description>&lt;p&gt;I Added Prometheus to My Go Job Scraper and It Changed How I Think About Production&lt;/p&gt;

&lt;p&gt;I was building a Go scraper for Google Jobs (&lt;a href="https://github.com/Aureliopires186/go-jobs-tracker" rel="noopener noreferrer"&gt;https://github.com/Aureliopires186/go-jobs-tracker&lt;/a&gt;) and I realized: if it runs in production and nobody can observe it, it doesn't exist.&lt;/p&gt;

&lt;p&gt;So I added Prometheus. Here's the exact minimal setup that made my project look senior-level.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Why Metrics Matter&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Without metrics, you are blind. You don't know:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How many jobs you scraped?&lt;/li&gt;
&lt;li&gt;Is it failing silently?&lt;/li&gt;
&lt;li&gt;How long does it take?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Prometheus solves that.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The Full Implementation&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Step A: Create &lt;code&gt;metrics/metrics.go&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
This is my live file: &lt;a href="https://github.com/Aureliopires186/go-jobs-tracker/tree/main/metrics" rel="noopener noreferrer"&gt;https://github.com/Aureliopires186/go-jobs-tracker/tree/main/metrics&lt;/a&gt;&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
go
package metrics

import (
    "github.com/prometheus/client_golang/prometheus"
    "github.com/prometheus/client_golang/prometheus/promauto"
)

var (
    JobsScraped = promauto.NewCounterVec(
        prometheus.CounterOpts{
            Name: "jobs_scraped_total",
            Help: "Total number of jobs scraped per engine and status",
        },
        []string{"engine", "status"},
    )

    ScrapeDuration = promauto.NewHistogramVec(
        prometheus.HistogramOpts{
            Name:    "scrape_duration_seconds",
            Help:    "Duration of scrape jobs in seconds",
            Buckets: prometheus.DefBuckets,
        },
        []string{"engine"},
    )

    ErrorsTotal = promauto.NewCounterVec(
        prometheus.CounterOpts{
            Name: "scraper_errors_total",
            Help: "Total scraper errors by type",
        },
        []string{"type"},
    )
)
*Step B: Expose /metrics and /healthz in `main.go`*
package main

import (
    "net/http"
    "time"
    "github.com/prometheus/client_golang/prometheus/promhttp"
    "github.com/Aureliopires186/go-jobs-tracker/metrics"
)

func main() {
    // Start metrics server
    go func() {
        http.Handle("/metrics", promhttp.Handler())
        http.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) {
            w.WriteHeader(200)
            w.Write([]byte("ok"))
        })
        http.ListenAndServe(":2112", nil)
    }()

    // Your scraping logic
    start := time.Now()
    // ... scrape ...
    duration := time.Since(start)

    metrics.JobsScraped.WithLabelValues("google_jobs", "success").Inc()
    metrics.ScrapeDuration.WithLabelValues("google_jobs").Observe(duration.Seconds())
}
*Step C: Install*
go get github.com/prometheus/client_golang@v1.19.0
go mod tidy
go run main.go
curl http://localhost:2112/metrics
You should see jobs_scraped_total
3. Docker + Prometheus Ready

My Dockerfile already exposes 2112.

`prometheus.yml`:
scrape_configs:
    - job_name: 'go-jobs-tracker'
    static_configs:
            - targets: ['localhost:2112']
Now you can create Grafana dashboards with `jobs_scraped_total` and `scrape_duration_seconds`.

4. What I Learned

Senior code is not about more features. It's about observability, health checks, and knowing when your system fails before the client does.

Full code: https://github.com/Aureliopires186/go-jobs-tracker

Follow me:
- LinkedIn: https://www.linkedin.com/in/pires-aur%C3%A9lio-511330385
- Blog: https://blogspotangola.blogspot.com/
- CoderLegion: https://coderlegion.com/user/Pires+Aurlio

If you are building scrapers in Go, add Prometheus on day 1. Your future self will thank you.

github.com/Aureliopires186/go-jobs-tracker/metrics
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>tutorial</category>
      <category>devops</category>
      <category>promothus</category>
      <category>opensource</category>
    </item>
    <item>
      <title>I Built a Production-Ready Job Queue in Go from Scratch - Goroutines, Postgres and Clean Architecture published: true</title>
      <dc:creator>Pires Aurélio</dc:creator>
      <pubDate>Thu, 01 Oct 2026 11:50:45 +0000</pubDate>
      <link>https://dev.to/aureliopires186/i-built-a-production-ready-job-queue-in-go-from-scratch-goroutines-postgres-and-clean-3dh8</link>
      <guid>https://dev.to/aureliopires186/i-built-a-production-ready-job-queue-in-go-from-scratch-goroutines-postgres-and-clean-3dh8</guid>
      <description>&lt;p&gt;--&lt;/p&gt;

&lt;p&gt;I'm  Pires Aurélio , a Go Backend Engineer from Luanda, Angola. I build production systems in public.&lt;/p&gt;

&lt;p&gt;For 2 years I built scrapers and REST APIs. I got tired of tutorials that only show "Hello World" with Gin. No jobs, no retries, no real problems.&lt;/p&gt;

&lt;p&gt;So I built a real one: A Production-Ready Background Job Queue in Go.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;My Public Work:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Main Scraper Framework (Python AsyncIO): &lt;a href="https://github.com/Aureliopires186/py-websites-scraper" rel="noopener noreferrer"&gt;https://github.com/Aureliopires186/py-websites-scraper&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Go Production Examples: &lt;a href="https://github.com/Aureliopires186/go-serpapi-examples" rel="noopener noreferrer"&gt;https://github.com/Aureliopires186/go-serpapi-examples&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Blog - REST API with Go (Gin): &lt;a href="https://blogspotangola.blogspot.com/2026/09/how-to-create-simple-rest-api-with.html" rel="noopener noreferrer"&gt;https://blogspotangola.blogspot.com/2026/09/how-to-create-simple-rest-api-with.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;LinkedIn / Portfolio: &lt;a href="https://www.linkedin.com/in/pires-aur%C3%A9lio-511330385" rel="noopener noreferrer"&gt;https://www.linkedin.com/in/pires-aur%C3%A9lio-511330385&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What We Are Building&lt;/p&gt;

&lt;p&gt;A REST API where you POST a task, it goes to Postgres, and Go workers process it in background with retries, rate limiting and graceful shutdown. Like Sidekiq / Celery, but in pure Go.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stack:&lt;/strong&gt; Go + Gin + Postgres + Goroutines + Docker&lt;br&gt;
&lt;strong&gt;Features:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;REST API with Clean Architecture&lt;/li&gt;
&lt;li&gt;Postgres as queue (no Redis needed)&lt;/li&gt;
&lt;li&gt;Worker Pool with 5 Goroutines&lt;/li&gt;
&lt;li&gt;Graceful Shutdown&lt;/li&gt;
&lt;li&gt;Retry with exponential backoff&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;Architecture (The Key for Recruiters)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Client -&amp;gt; POST /jobs -&amp;gt; API (Gin) -&amp;gt; Postgres (jobs table) -&amp;gt; Worker Pool -&amp;gt; Process -&amp;gt; Update Status&lt;/p&gt;

&lt;p&gt;Why Postgres and not Redis? For portfolio and for cost. One less service. And it proves you understand ACID, transactions and &lt;code&gt;FOR UPDATE SKIP LOCKED&lt;/code&gt;.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Database Schema - The Foundation&lt;/li&gt;
&lt;/ol&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
sql
CREATE TABLE jobs (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  payload JSONB NOT NULL,
  status VARCHAR(20) DEFAULT 'pending',
  attempts INT DEFAULT 0,
  max_attempts INT DEFAULT 3,
  created_at TIMESTAMPTZ DEFAULT NOW(),
  next_retry_at TIMESTAMPTZ DEFAULT NOW()
);

CREATE INDEX idx_jobs_status_next_retry ON jobs(status, next_retry_at);
This index `idx_jobs_status_next_retry` is critical. It makes the worker query O(log n) even with 1 million jobs.

3. The Worker - The Heart of the System

This is what 90% of tutorials don't teach. This is what makes you Senior.
package worker

import (
  "context"
  "log"
  "math"
  "time"
)

func (w *Worker) Start(ctx context.Context) {
  for i := 0; i &amp;lt; w.concurrency; i++ {
    go func(workerID int) {
      log.Printf("Worker %d started", workerID)
      for {
        select {
        case &amp;lt;-ctx.Done():
          log.Printf("Worker %d shutting down gracefully", workerID)
          return
        default:
          job, err := w.repo.FetchPendingJob(ctx) // Uses FOR UPDATE SKIP LOCKED
          if err!= nil {
            time.Sleep(1 * time.Second)
            continue
          }
          if job == nil {
            time.Sleep(500 * time.Millisecond)
            continue
          }
          w.processWithRetry(ctx, job)
        }
      }
    }(i)
  }
}

func (w *Worker) processWithRetry(ctx context.Context, job *Job) {
  err := w.processor.Process(job)
  if err!= nil {
    job.Attempts++
    if job.Attempts &amp;gt;= job.MaxAttempts {
      w.repo.MarkFailed(ctx, job.ID)
      log.Printf("Job %s failed permanently after %d attempts", job.ID, job.Attempts)
    } else {
      backoff := time.Duration(math.Pow(2, float64(job.Attempts))) * time.Second
      w.repo.MarkForRetry(ctx, job.ID, time.Now().Add(backoff))
      log.Printf("Job %s failed, retrying in %v", job.ID, backoff)
    }
    return
  }
  w.repo.MarkDone(ctx, job.ID)
}
*What recruiters see here:*
1. `FOR UPDATE SKIP LOCKED` - You know how to prevent double-processing
2. `context.Context` - You know Graceful Shutdown
3. Exponential Backoff - You think about production resilience

4. The Repository Query (The Secret Sauce)
func (r *JobRepo) FetchPendingJob(ctx context.Context) (*Job, error) {
  query := `
    SELECT id, payload, attempts, max_attempts
    FROM jobs
    WHERE status = 'pending' AND next_retry_at &amp;lt;= NOW()
    ORDER BY created_at ASC
    LIMIT 1
    FOR UPDATE SKIP LOCKED`

  // This SKIP LOCKED is GOLD. Two workers will never get the same job.
  //...
}
5. REST API with Gin - Clean Handler
func (h *JobHandler) CreateJob(c *gin.Context) {
  var req CreateJobRequest
  if err := c.ShouldBindJSON(&amp;amp;req); err!= nil {
    c.JSON(400, gin.H{"error": err.Error()})
    return
  }
  job, err := h.service.Enqueue(c.Request.Context(), req.Payload)
  if err!= nil {
    c.JSON(500, gin.H{"error": "failed to enqueue job"})
    return
  }
  c.JSON(201, job)
}

func (h *JobHandler) ListJobs(c *gin.Context) {
  jobs, _ := h.service.List(c.Request.Context())
  c.JSON(200, jobs)
}
No business logic in handler. That's Clean Architecture. Handler -&amp;gt; Service -&amp;gt; Repo.

6. Docker Compose - One Command Run
version: '3.8'
services:
  api:
    build:.
    ports: ["8080:8080"]
    environment:
      - DATABASE_URL=postgres://postgres:postgres@db:5432/jobs?sslmode=disable
    depends_on: [db]
  db:
    image: postgres:15
    environment:
      - POSTGRES_DB=jobs
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
    ports: ["5432:5432"]
`docker-compose up` and the whole system is up.

7. What I Learned Building This in Luanda

1. *Concurrency is not parallelism:* Goroutines are cheap (2KB), but Postgres connections are not. I use a pgx pool with max 10 connections.
2. *Observability from day 1:* I added JobID in every log. In a real company, this would be Prometheus + Grafana.
3. *Failure is the default:* 80% of the code is handling retries, shutdown, and errors. 20% is the happy path.

Conclusion

Any junior can build a CRUD. A mid-level builds a system that doesn't break when 10,000 jobs arrive at once.

This project proves:
- You understand Go concurrency
- You understand databases beyond SELECT *
- You think about failure, not just success

Full code of this queue is coming to my GitHub next week. Follow for Part 2: Adding Rate Limiter, Metrics and Dead Letter Queue.

Built in public from Luanda, Angola 🇦🇴

If you are a recruiter looking for a Go backend engineer who ships production-ready systems, let's talk.

---
Examples using public technologies. All code is my own. Not affiliated with any provider.

Author : pires Aurélio 
E-mail: aureliopires186@gmail.com 
https://www.linkedin.com/in/pires-aur%C3%A9lio-511330385
https://github.com/Aureliopires186
https://coderlegion.com/user/Pires+Aurlio
https://blogspotangola.blogspot.com/2026/09/building-production-ready-google-jobs.html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>webdev</category>
      <category>tutorial</category>
      <category>opensource</category>
      <category>api</category>
    </item>
    <item>
      <title>I Migrated from Python Scrapers to Go and Search APIs - Complete Guide published: true</title>
      <dc:creator>Pires Aurélio</dc:creator>
      <pubDate>Tue, 29 Sep 2026 18:17:18 +0000</pubDate>
      <link>https://dev.to/aureliopires186/i-migrated-from-python-scrapers-to-go-serpapi-complete-guidepublished-true-bc3</link>
      <guid>https://dev.to/aureliopires186/i-migrated-from-python-scrapers-to-go-serpapi-complete-guidepublished-true-bc3</guid>
      <description>&lt;p&gt;•Observation :&lt;br&gt;
 Examples using public third-party APIs. Not affiliated with or endorsed by any API provider. All trademarks belong to their respective owners.&lt;/p&gt;

&lt;p&gt;I'm Pires Aurélio , a Go/Python developer from Angola. I build scrapers in production and document everything in public.&lt;/p&gt;

&lt;p&gt;My work:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Main scraper (Python/AsyncIO)&lt;/strong&gt;: &lt;a href="https://github.com/Aureliopires186/py-websites-scraper" rel="noopener noreferrer"&gt;https://github.com/Aureliopires186/py-websites-scraper&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Go SerpApi Examples&lt;/strong&gt;: &lt;a href="https://github.com/Aureliopires186/go-serpapi-examples" rel="noopener noreferrer"&gt;https://github.com/Aureliopires186/go-serpapi-examples&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Jobs Scraper Tracker&lt;/strong&gt;: &lt;a href="https://github.com/Aureliopires186/-serpApi-go-jobs-scraper/issues/3" rel="noopener noreferrer"&gt;https://github.com/Aureliopires186/-serpApi-go-jobs-scraper/issues/3&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Blog - How to build REST API in Go&lt;/strong&gt;: &lt;a href="https://blogspotangola.blogspot.com/2026/09/how-to-create-simple-rest-api-with.html" rel="noopener noreferrer"&gt;https://blogspotangola.blogspot.com/2026/09/how-to-create-simple-rest-api-with.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;LinkedIn&lt;/strong&gt;: &lt;a href="https://www.linkedin.com/in/pires-aur%C3%A9lio-511330385" rel="noopener noreferrer"&gt;https://www.linkedin.com/in/pires-aur%C3%A9lio-511330385&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For 2 years I scraped sites with pure Python/Go. Then I hit Google. Everything broke.&lt;/p&gt;

&lt;p&gt;This tutorial is how I solved it with Go + SerpApi.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Why My Python Scraper Failed on Google
&lt;/h3&gt;

&lt;p&gt;My repo &lt;code&gt;py-websites-scraper&lt;/code&gt; uses &lt;code&gt;asyncio + aiohttp + readability-lxml&lt;/code&gt;. Great for blogs.&lt;/p&gt;

&lt;p&gt;But for Google Jobs / Shopping:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CAPTCHA in 10 requests&lt;/li&gt;
&lt;li&gt;429 blocks&lt;/li&gt;
&lt;li&gt;Selectors change weekly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I was spending 80% time fighting anti-bot, 20% building features. Wrong.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Why SerpApi + Go Is The Stack
&lt;/h3&gt;

&lt;p&gt;SerpApi handles proxies, CAPTCHAs, parsing. You get clean JSON.&lt;br&gt;
Go handles concurrency perfectly.&lt;/p&gt;

&lt;p&gt;My stack now: Go + SerpApi + Gin REST API (as I teach in my blog)&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Setup (2 minutes)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
bash
go mod init go-serpapi-demo
go get github.com/serpapi/google-search-results-golang
go get github.com/gin-gonic/gin
export SERPAPI_KEY=your_free_key_from_serpapi.com

#. Example 1: Google Jobs - The Code I Use

package main

import (
  "fmt"
  "log"
  "os"

  g "github.com/serpapi/google-search-results-golang"
)

// Só pegamos o que vamos usar - tipo seguro
type Job struct {
  Title string `json:"title"`
  CompanyName string `json:"company_name"`
  Via string `json:"via"`
}

func main() {
  apiKey := os.Getenv("SERPAPI_KEY")
  if apiKey == "" {
    log.Fatal("SERPAPI_KEY not set")
  }

  params := map[string]string{
    "engine": "google_jobs",
    "q": "Go Developer",
    "location": "Remote",
    "hl": "en",
  }

  search := g.NewGoogleSearch(params, apiKey)
  results, err := search.GetJSON()
  if err!= nil {
    log.Fatalf("SerpApi request failed: %v", err)
  }

  // FORMA SEGURA que o Mike pediu
  jobsRaw, ok := results["jobs_results"].([]interface{})
  if!ok {
    log.Printf("No jobs_results in response: %+v", results)
    return
  }

  if len(jobsRaw) == 0 {
    fmt.Println("No jobs found")
    return
  }

  for _, j := range jobsRaw {
    jobMap, ok := j.(map[string]interface{})
    if!ok {
      continue // pula item estranho sem quebrar
    }
    // print seguro
    fmt.Printf("[%v] %v - %v\n", jobMap["via"], jobMap["title"], jobMap["company_name"])
  }
}

#. Example 2: Google Shopping Price Tracker

package main

import (
  "fmt"
  "log"
  "os"

  g "github.com/serpapi/google-search-results-golang"
)

func main() {
  apiKey := os.Getenv("SERPAPI_KEY")
  if apiKey == "" {
    log.Fatal("SERPAPI_KEY not set")
  }

  params := map[string]string{
    "engine": "google_shopping",
    "q": "golang book",
  }

  search := g.NewGoogleSearch(params, apiKey)

  // NUNCA ignore erro - correção do Mike
  results, err := search.GetJSON()
  if err!= nil {
    log.Fatalf("failed to get shopping results: %v", err)
  }

  shoppingResults, ok := results["shopping_results"].([]interface{})
  if!ok {
    log.Printf("No shopping_results found: %+v", results)
    return
  }

  fmt.Printf("Found %d products\n", len(shoppingResults))
  for _, item := range shoppingResults {
    if m, ok := item.(map[string]interface{}); ok {
      fmt.Printf("- %v: %v\n", m["title"], m["price"])
    }
  }
}


By:Pires Aurélio 
Contact: aureliopires186@gmail.com 
https://blogspotangola.blogspot.com/?m=1
https://www.linkedin.com/in/pires-aur%C3%A9lio-511330385

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

&lt;/div&gt;

</description>
      <category>webdev</category>
      <category>tutorial</category>
      <category>opensource</category>
      <category>api</category>
    </item>
    <item>
      <title>I Open-Sourced 5 Real-World API Integration Examples with Go (Gin) — Here's What I Learned</title>
      <dc:creator>Pires Aurélio</dc:creator>
      <pubDate>Wed, 23 Sep 2026 19:18:11 +0000</pubDate>
      <link>https://dev.to/aureliopires186/i-open-sourced-5-real-world-api-examples-with-go-and-serpapi-heres-what-i-learned-87k</link>
      <guid>https://dev.to/aureliopires186/i-open-sourced-5-real-world-api-examples-with-go-and-serpapi-heres-what-i-learned-87k</guid>
      <description>&lt;h1&gt;
  
  
  I Open-Sourced 5 Real-World API Integration Examples with Go (Gin) — Here's What I Learned
&lt;/h1&gt;

&lt;p&gt;•Observation :&lt;br&gt;
Examples using public third-party APIs. Not affiliated with or endorsed by any API provider. All trademarks belong to their respective owners.&lt;/p&gt;

&lt;p&gt;I love Go for its simplicity. But finding clean, real-world examples of how to use Search APIs with Go is hard. So I decided to build it myself.&lt;/p&gt;

&lt;p&gt;I'm excited to share my new open-source project:&lt;/p&gt;

&lt;h3&gt;
  
  
  👉 &lt;a href="https://github.com/Aureliopires186/go-serpapi-examples" rel="noopener noreferrer"&gt;https://github.com/Aureliopires186/go-serpapi-examples&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;The goal is simple: help Go developers in Africa and around the world build products with real-time data without dealing with scraping, proxies, or captchas.&lt;/p&gt;

&lt;h3&gt;
  
  
  What's inside?
&lt;/h3&gt;

&lt;p&gt;The repo is not just one example, it's a collection of ready-to-use REST APIs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ &lt;strong&gt;Google Jobs API&lt;/strong&gt; – Build your own job board (perfect for remote jobs)&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;Google Maps API&lt;/strong&gt; – Location search &amp;amp; place details&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;Google Search API&lt;/strong&gt; – SERP tracking tool&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;All built with clean Go, Gin, and best practices&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each example has a &lt;code&gt;README.md&lt;/code&gt; with step-by-step instructions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why SerpApi + Go?
&lt;/h3&gt;

&lt;p&gt;I tested scraping myself. It broke every week. SerpApi just works and returns clean JSON. For Go developers, that's gold. You focus on &lt;code&gt;go run&lt;/code&gt;, not on fixing parsers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Full Tutorial
&lt;/h3&gt;

&lt;p&gt;I wrote a detailed breakdown of how I built the Jobs API on my blog:&lt;/p&gt;

&lt;p&gt;📖 Read the full tutorial: &lt;a href="https://blogspotangola.blogspot.com/2026/09/how-to-create-simple-rest-api-with.html" rel="noopener noreferrer"&gt;https://blogspotangola.blogspot.com/2026/09/how-to-create-simple-rest-api-with.html&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What's next?
&lt;/h3&gt;

&lt;p&gt;This is just the start. I want to add more APIs (Flights, Shopping, Scholar) and create video tutorials.&lt;/p&gt;

&lt;p&gt;If this project helped you, please:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; ⭐ &lt;strong&gt;Star the repo&lt;/strong&gt; to support the work&lt;/li&gt;
&lt;li&gt; 💬 &lt;strong&gt;Open an issue&lt;/strong&gt; telling me what example you want next&lt;/li&gt;
&lt;li&gt; 🔗 &lt;strong&gt;Connect with me&lt;/strong&gt;, I'm documenting my journey to becoming a Developer Advocate&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Let's connect:&lt;/strong&gt;&lt;br&gt;
LinkedIn: &lt;a href="https://www.linkedin.com/in/pires-aur%C3%A9lio-511330385" rel="noopener noreferrer"&gt;https://www.linkedin.com/in/pires-aur%C3%A9lio-511330385&lt;/a&gt;&lt;br&gt;
My Blog: &lt;a href="https://blogspotangola.blogspot.com/" rel="noopener noreferrer"&gt;https://blogspotangola.blogspot.com/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thanks for reading! What API would you build first?&lt;/p&gt;

&lt;p&gt;Author : pires Aurélio &lt;br&gt;
E-mail: &lt;a href="mailto:aureliopires186@gmail.com"&gt;aureliopires186@gmail.com&lt;/a&gt; &lt;br&gt;
&lt;a href="https://coderlegion.com/user/Pires+Aurlio" rel="noopener noreferrer"&gt;https://coderlegion.com/user/Pires+Aurlio&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Aureliopires186" rel="noopener noreferrer"&gt;https://github.com/Aureliopires186&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.linkedin.com/in/pires-aur%C3%A9lio-511330385" rel="noopener noreferrer"&gt;https://www.linkedin.com/in/pires-aur%C3%A9lio-511330385&lt;/a&gt;&lt;br&gt;
&lt;a href="https://blogspotangola.blogspot.com/2026/09/building-production-ready-google-jobs.html" rel="noopener noreferrer"&gt;https://blogspotangola.blogspot.com/2026/09/building-production-ready-google-jobs.html&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>devops</category>
      <category>seo</category>
      <category>api</category>
    </item>
    <item>
      <title>Search Google Jobs in Real-Time with Go 🚀</title>
      <dc:creator>Pires Aurélio</dc:creator>
      <pubDate>Wed, 23 Sep 2026 10:13:52 +0000</pubDate>
      <link>https://dev.to/aureliopires186/search-google-jobs-in-real-time-with-go-and-serpapi-690</link>
      <guid>https://dev.to/aureliopires186/search-google-jobs-in-real-time-with-go-and-serpapi-690</guid>
      <description>&lt;p&gt;•Observation :&lt;br&gt;
 Examples using public third-party APIs. Not affiliated with or endorsed by any API provider. All trademarks belong to their respective owners.&lt;/p&gt;

&lt;p&gt;Hey devs! 👋&lt;/p&gt;

&lt;p&gt;Tired of manual scraping to get Google Jobs listings? 🤔&lt;/p&gt;

&lt;p&gt;I built a Go example that uses the SerpApi to fetch Google Jobs data in real-time! 👀&lt;/p&gt;

&lt;p&gt;🔍 What this tutorial covers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How to set up SerpApi&lt;/li&gt;
&lt;li&gt;Searching jobs with Go&lt;/li&gt;
&lt;li&gt;Parsing results to JSON&lt;/li&gt;
&lt;li&gt;Deploying the API to the cloud&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Links:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://blogspotangola.blogspot.com/2026/09/how-to-search-google-jobs-in-real-time.html" rel="noopener noreferrer"&gt;Read the full tutorial on my blog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Aureliopires186/go-serpapi-examples" rel="noopener noreferrer"&gt;Code on GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.linkedin.com/in/pires-aur%C3%A9lio-51133038" rel="noopener noreferrer"&gt;Connect with me on LinkedIn&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;💡 Need help with automation? Feel free to reach out!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>devops</category>
      <category>tutorial</category>
      <category>api</category>
    </item>
  </channel>
</rss>
