Create API client

pull/24/head
Aloïs Micard 4 years ago
parent 1c8368704c
commit 20f67edd28
No known key found for this signature in database
GPG Key ID: 1A0EB82F071F5EFE

@ -0,0 +1,105 @@
package api
import (
"bytes"
"encoding/json"
"fmt"
"github.com/rs/zerolog/log"
"net/http"
"time"
)
const contentTypeJSON = "application/json"
// ResourceDto represent a resource as given by the API
type ResourceDto struct {
URL string `json:"url"`
Body string `json:"body"`
Title string `json:"title"`
Time time.Time `json:"time"`
}
type Client interface {
SearchResources(url string) ([]ResourceDto, error)
AddResource(res ResourceDto) (ResourceDto, error)
AddURL(url string) error
}
type client struct {
httpClient *http.Client
baseURL string
}
func (c *client) SearchResources(url string) ([]ResourceDto, error) {
targetEndpoint := fmt.Sprintf("%s/v1/resources", c.baseURL)
if url != "" {
targetEndpoint += "?url=" + url
}
var resources []ResourceDto
_, err := jsonGet(c.httpClient, targetEndpoint, &resources)
return resources, err
}
func (c *client) AddResource(res ResourceDto) (ResourceDto, error) {
targetEndpoint := fmt.Sprintf("%s/v1/resources", c.baseURL)
var resourceDto ResourceDto
_, err := jsonPost(c.httpClient, targetEndpoint, res, &resourceDto)
return resourceDto, err
}
func (c *client) AddURL(url string) error {
targetEndpoint := fmt.Sprintf("%s/v1/urls", c.baseURL)
_, err := jsonPost(c.httpClient, targetEndpoint, url, nil)
return err
}
func NewClient(baseURL string) Client {
return &client{
httpClient: &http.Client{},
baseURL: baseURL,
}
}
func jsonGet(httpClient *http.Client, url string, response interface{}) (*http.Response, error) {
log.Trace().Str("verb", "GET").Str("url", url).Msg("")
r, err := httpClient.Get(url)
if err != nil {
return nil, err
}
if err := json.NewDecoder(r.Body).Decode(&response); err != nil {
return nil, err
}
return r, nil
}
func jsonPost(httpClient *http.Client, url string, request, response interface{}) (*http.Response, error) {
log.Trace().Str("verb", "POST").Str("url", url).Msg("")
var err error
var b []byte
if request != nil {
b, err = json.Marshal(request)
if err != nil {
return nil, err
}
}
r, err := httpClient.Post(url, contentTypeJSON, bytes.NewBuffer(b))
if err != nil {
return nil, err
}
if response != nil {
if err := json.NewDecoder(r.Body).Decode(&response); err != nil {
return nil, err
}
}
return r, nil
}

@ -1,11 +0,0 @@
package api
import "time"
// ResourceDto represent a resource as given by the API
type ResourceDto struct {
URL string `json:"url"`
Body string `json:"body"`
Title string `json:"title"`
Time time.Time `json:"time"`
}

@ -1,7 +1,7 @@
package extractor
import (
"github.com/creekorful/trandoshan/internal/util/http"
"github.com/creekorful/trandoshan/api"
"github.com/creekorful/trandoshan/internal/util/logging"
natsutil "github.com/creekorful/trandoshan/internal/util/nats"
"github.com/creekorful/trandoshan/messaging"
@ -41,8 +41,8 @@ func execute(ctx *cli.Context) error {
log.Debug().Str("uri", ctx.String("nats-uri")).Msg("Using NATS server")
log.Debug().Str("uri", ctx.String("api-uri")).Msg("Using API server")
// Create the HTTP client
httpClient := &http.Client{}
// Create the API client
apiClient := api.NewClient(ctx.String("api-uri"))
// Create the NATS subscriber
sub, err := natsutil.NewSubscriber(ctx.String("nats-uri"))
@ -53,14 +53,14 @@ func execute(ctx *cli.Context) error {
log.Info().Msg("Successfully initialized tdsh-extractor. Waiting for resources")
if err := sub.QueueSubscribe(messaging.NewResourceSubject, "extractors", handleMessage(httpClient, ctx.String("api-uri"))); err != nil {
if err := sub.QueueSubscribe(messaging.NewResourceSubject, "extractors", handleMessage(apiClient, ctx.String("api-uri"))); err != nil {
return err
}
return nil
}
func handleMessage(apiClient *http.Client, apiURI string) natsutil.MsgHandler {
func handleMessage(apiClient api.Client, apiURI string) natsutil.MsgHandler {
return func(nc *nats.Conn, msg *nats.Msg) error {
var resMsg messaging.NewResourceMsg
if err := natsutil.ReadMsg(msg, &resMsg); err != nil {

@ -1,8 +1,7 @@
package feeder
import (
"fmt"
"github.com/creekorful/trandoshan/internal/util/http"
"github.com/creekorful/trandoshan/api"
"github.com/creekorful/trandoshan/internal/util/logging"
"github.com/rs/zerolog/log"
"github.com/urfave/cli/v2"
@ -38,11 +37,8 @@ func execute(ctx *cli.Context) error {
log.Debug().Str("uri", ctx.String("api-uri")).Msg("Using API server")
apiURL := fmt.Sprintf("%s/v1/urls", ctx.String("api-uri"))
c := http.Client{}
_, err := c.JSONPost(apiURL, ctx.String("url"), nil)
if err != nil {
apiClient := api.NewClient(ctx.String("api-uri"))
if err := apiClient.AddURL(ctx.String("url")); err != nil {
log.Err(err).Msg("Unable to publish URL")
return err
}

@ -5,7 +5,6 @@ import (
"fmt"
"github.com/PuerkitoBio/purell"
"github.com/creekorful/trandoshan/api"
"github.com/creekorful/trandoshan/internal/util/http"
"github.com/creekorful/trandoshan/internal/util/logging"
natsutil "github.com/creekorful/trandoshan/internal/util/nats"
"github.com/creekorful/trandoshan/messaging"
@ -47,8 +46,8 @@ func execute(ctx *cli.Context) error {
log.Debug().Str("uri", ctx.String("nats-uri")).Msg("Using NATS server")
log.Debug().Str("uri", ctx.String("api-uri")).Msg("Using API server")
// Create the HTTP client
httpClient := &http.Client{}
// Create the API client
apiClient := api.NewClient(ctx.String("api-uri"))
// Create the NATS subscriber
sub, err := natsutil.NewSubscriber(ctx.String("nats-uri"))
@ -59,14 +58,14 @@ func execute(ctx *cli.Context) error {
log.Info().Msg("Successfully initialized tdsh-scheduler. Waiting for URLs")
if err := sub.QueueSubscribe(messaging.URLFoundSubject, "schedulers", handleMessage(httpClient, ctx.String("api-uri"))); err != nil {
if err := sub.QueueSubscribe(messaging.URLFoundSubject, "schedulers", handleMessage(apiClient, ctx.String("api-uri"))); err != nil {
return err
}
return nil
}
func handleMessage(apiClient *http.Client, apiURI string) natsutil.MsgHandler {
func handleMessage(apiClient api.Client, apiURI string) natsutil.MsgHandler {
return func(nc *nats.Conn, msg *nats.Msg) error {
var urlMsg messaging.URLFoundMsg
if err := natsutil.ReadJSON(msg, &urlMsg); err != nil {
@ -87,10 +86,7 @@ func handleMessage(apiClient *http.Client, apiURI string) natsutil.MsgHandler {
}
b64URI := base64.URLEncoding.EncodeToString([]byte(normalizedURL.String()))
apiURL := fmt.Sprintf("%s/v1/resources?url=%s", apiURI, b64URI)
var urls []api.ResourceDto
_, err = apiClient.JSONGet(apiURL, &urls)
urls, err := apiClient.SearchResources(b64URI)
if err != nil {
log.Err(err).Msg("Error while searching URL")
return err

@ -1,61 +0,0 @@
package http
import (
"bytes"
"encoding/json"
"github.com/rs/zerolog/log"
"net/http"
)
// StatusCreated HTTP 201
const StatusCreated = 201
const contentTypeJSON = "application/json"
// Client an http client with built-in JSON (de)serialization
type Client struct {
client http.Client
}
// JSONGet perform a GET request and serialize response body into given interface if any
func (c *Client) JSONGet(url string, response interface{}) (*http.Response, error) {
log.Trace().Str("verb", "GET").Str("url", url).Msg("")
r, err := c.client.Get(url)
if err != nil {
return nil, err
}
if err := json.NewDecoder(r.Body).Decode(&response); err != nil {
return nil, err
}
return r, nil
}
// JSONPost perform a POST request and serialize request/response body into given interface if any
func (c *Client) JSONPost(url string, request, response interface{}) (*http.Response, error) {
log.Trace().Str("verb", "POST").Str("url", url).Msg("")
var err error
var b []byte
if request != nil {
b, err = json.Marshal(request)
if err != nil {
return nil, err
}
}
r, err := c.client.Post(url, contentTypeJSON, bytes.NewBuffer(b))
if err != nil {
return nil, err
}
if response != nil {
if err := json.NewDecoder(r.Body).Decode(&response); err != nil {
return nil, err
}
}
return r, nil
}
Loading…
Cancel
Save