Go Email Validation
Complete guide to email validation in Go
What You'll Learn
- Integrate VerifyForge API using Go's HTTP client
- Create reusable validation functions
- Handle errors with Go patterns
- Implement concurrent bulk validation
- Best practices for production
Prerequisites
- Go 1.20+ installed
- Basic knowledge of Go
- VerifyForge API key (get free key)
Quick Start
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
)
func main() {
apiKey := "your_api_key"
email := "user@example.com"
client := &http.Client{}
req, _ := http.NewRequest("GET",
"https://verifyforge.com/api/validate?email="+url.QueryEscape(email),
nil)
req.Header.Set("X-API-Key", apiKey)
resp, err := client.Do(req)
if err != nil {
fmt.Println("Error:", err)
return
}
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
var result map[string]interface{}
json.Unmarshal(body, &result)
data := result["data"].(map[string]interface{})
fmt.Printf("Valid: %v\n", data["isValid"])
}
Email Validator Package
// emailvalidator/validator.go
package emailvalidator
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"time"
)
type Client struct {
APIKey string
BaseURL string
client *http.Client
}
type ValidationResult struct {
Email string `json:"email"`
IsValid bool `json:"isValid"`
Reachability string `json:"reachability"`
Disposable bool `json:"disposable"`
RoleAccount bool `json:"roleAccount"`
FreeProvider bool `json:"freeProvider"`
Suggestion string `json:"suggestion,omitempty"`
}
type ValidationResponse struct {
Success bool `json:"success"`
Data ValidationResult `json:"data"`
}
func NewClient(apiKey string) *Client {
return &Client{
APIKey: apiKey,
BaseURL: "https://verifyforge.com",
client: &http.Client{
Timeout: 30 * time.Second,
},
}
}
func (c *Client) Validate(email string) (*ValidationResult, error) {
req, err := http.NewRequest("GET",
fmt.Sprintf("%s/api/validate?email=%s", c.BaseURL, url.QueryEscape(email)),
nil)
if err != nil {
return nil, err
}
req.Header.Set("X-API-Key", c.APIKey)
resp, err := c.client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("API error: %d", resp.StatusCode)
}
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}
var result ValidationResponse
if err := json.Unmarshal(body, &result); err != nil {
return nil, err
}
return &result.Data, nil
}
func (c *Client) ValidateBulk(emails []string) ([]ValidationResult, error) {
payload, err := json.Marshal(map[string][]string{"emails": emails})
if err != nil {
return nil, err
}
req, err := http.NewRequest("POST",
fmt.Sprintf("%s/api/validate/bulk", c.BaseURL),
bytes.NewBuffer(payload))
if err != nil {
return nil, err
}
req.Header.Set("X-API-Key", c.APIKey)
req.Header.Set("Content-Type", "application/json")
resp, err := c.client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}
var result struct {
Data struct {
Results []ValidationResult `json:"results"`
} `json:"data"`
}
if err := json.Unmarshal(body, &result); err != nil {
return nil, err
}
return result.Data.Results, nil
}
HTTP Handler Example
package main
import (
"encoding/json"
"log"
"net/http"
"os"
"yourapp/emailvalidator"
)
var validator *emailvalidator.Client
func init() {
validator = emailvalidator.NewClient(os.Getenv("VERIFYFORGE_API_KEY"))
}
func validateHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
return
}
var req struct {
Email string `json:"email"`
}
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, "Invalid request", http.StatusBadRequest)
return
}
result, err := validator.Validate(req.Email)
if err != nil {
http.Error(w, "Validation failed", http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(map[string]interface{}{
"success": true,
"data": result,
})
}
func main() {
http.HandleFunc("/api/validate", validateHandler)
log.Fatal(http.ListenAndServe(":8080", nil))
}
Concurrent Bulk Validation
package main
import (
"sync"
"yourapp/emailvalidator"
)
func validateConcurrent(emails []string, validator *emailvalidator.Client) map[string]*emailvalidator.ValidationResult {
results := make(map[string]*emailvalidator.ValidationResult)
var mu sync.Mutex
var wg sync.WaitGroup
for _, email := range emails {
wg.Add(1)
go func(e string) {
defer wg.Done()
result, err := validator.Validate(e)
if err == nil {
mu.Lock()
results[e] = result
mu.Unlock()
}
}(email)
}
wg.Wait()
return results
}
