Skip to content

Commit

Permalink
Split into multiple packages and improve error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
th0th committed Nov 7, 2020
1 parent d701856 commit c2336cd
Show file tree
Hide file tree
Showing 3 changed files with 127 additions and 65 deletions.
50 changes: 50 additions & 0 deletions domain/domain.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package domain

import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
)

type Domain struct {
domains map[string]bool
}

func NewDomain() (*Domain, error) {
var err error

domainsJsonFile, err := os.Open("domains.json")

if err != nil {
return nil, fmt.Errorf("an error occurred while opening the domains file: %v", err)
}

byteValue, err := ioutil.ReadAll(domainsJsonFile)

if err != nil {
return nil, fmt.Errorf("an error occurred while reading the domains file: %v", err)
}

var domainsSlice []string

err = json.Unmarshal(byteValue, &domainsSlice)

if err != nil {
return nil, fmt.Errorf("an error occurred while parsing the domains file: %v", err)
}

domains := make(map[string]bool)

for _, domain := range domainsSlice {
domains[domain] = true
}

return &Domain{
domains: domains,
}, nil
}

func (d *Domain) GetIsDisposable(emailOrDomain string) bool {
return d.domains[emailOrDomain]
}
69 changes: 69 additions & 0 deletions http/server.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package http

import (
"encoding/json"
"github.com/julienschmidt/httprouter"
"log"
"net/http"
"strings"
)

type domain interface {
GetIsDisposable(string) bool
}

type Server struct {
domain domain
}

type ErrorResponse struct {
Detail string `json:"detail"`
}

type Response struct {
IsDisposable bool `json:"isDisposable"`
}

func NewServer(d domain) Server {
return Server{
domain: d,
}
}

func (s *Server) index(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
queryParams := r.URL.Query()
email := queryParams.Get("email")

w.Header().Set("Content-Type", "application/json")

if email == "" {
errorResponse, _ := json.Marshal(ErrorResponse{
Detail: "email query parameter should be set.",
})

w.WriteHeader(400)
w.Write(errorResponse)

return
}

parts := strings.Split(email, "@")
emailDomain := parts[len(parts)-1]

isDisposable := s.domain.GetIsDisposable(emailDomain)

jsonBytes, _ := json.Marshal(Response{
IsDisposable: isDisposable,
})

w.Write(jsonBytes)
}

func (s *Server) Run() {
router := httprouter.New()

router.GET("/", s.index)

log.Println("Starting to listen on 0.0.0.0:80...")
log.Fatal(http.ListenAndServe(":80", router))
}
73 changes: 8 additions & 65 deletions main.go
Original file line number Diff line number Diff line change
@@ -1,76 +1,19 @@
package main

import (
"encoding/json"
"github.com/julienschmidt/httprouter"
"io/ioutil"
"github.com/th0th/is-email-disposable/domain"
"github.com/th0th/is-email-disposable/http"
"log"
"net/http"
"os"
"strings"
)

type ErrorResponse struct {
Detail string `json:"detail"`
}

type Response struct {
IsDisposable bool `json:"isDisposable"`
}

var domains []string

func handler(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
queryParams := r.URL.Query()

email := queryParams.Get("email")

w.Header().Set("Content-Type", "application/json")

if email == "" {
errorResponse, _ := json.Marshal(ErrorResponse{
Detail: "email query parameter should be set.",
})

w.WriteHeader(400)
w.Write(errorResponse)

return
}

parts := strings.Split(email, "@")
domain := parts[len(parts)-1]

isDisposable := Find(domains, domain)

jsonBytes, _ := json.Marshal(Response{
IsDisposable: isDisposable,
})

w.Write(jsonBytes)
}

func main() {
domainsJsonFile, _ := os.Open("domains.json")

byteValue, _ := ioutil.ReadAll(domainsJsonFile)
d, err := domain.NewDomain()

_ = json.Unmarshal(byteValue, &domains)

router := httprouter.New()

router.GET("/", handler)

log.Println("Starting to listen on 0.0.0.0:80...")
log.Fatal(http.ListenAndServe(":80", router))
}

func Find(slice []string, val string) bool {
for _, item := range slice {
if item == val {
return true
}
if err != nil {
log.Panic(err)
}

return false
server := http.NewServer(d)

server.Run()
}

0 comments on commit c2336cd

Please sign in to comment.