Skip to content

Commit

Permalink
Extracted Client (cayleygraph#896)
Browse files Browse the repository at this point in the history
* Code generated client

* Fix query result type and code generation

* Make client importable

* Refactor server/http tests to not rely on client

* Reduce magic strings

* Reduce JSON LD mentions

* Revert all non-server changes

* Restore client

* Add deprecation note regarding client

* Make write response private
  • Loading branch information
iddan authored Jan 3, 2020
1 parent 3cc8244 commit 80bd8af
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 36 deletions.
3 changes: 3 additions & 0 deletions client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ func New(addr string) *Client {
return &Client{addr: addr, cli: http.DefaultClient}
}

// Client is a struct used for communicating with a Cayley server through HTTP
// Deprecated: Client exists for backwards compatability. New code should use
// the updated client github.com/cayleygraph/go-client
type Client struct {
addr string
cli *http.Client
Expand Down
16 changes: 10 additions & 6 deletions docs/api/swagger.yml
Original file line number Diff line number Diff line change
Expand Up @@ -329,9 +329,7 @@ paths:
content:
'application/json':
schema:
oneOf:
- type: "array"
- type: "object"
$ref: '#/components/schemas/QueryResult'
default:
description: "Unexpected error"
content:
Expand Down Expand Up @@ -376,9 +374,7 @@ paths:
content:
'application/json':
schema:
oneOf:
- type: "array"
- type: "object"
$ref: '#/components/schemas/QueryResult'
default:
description: "Unexpected error"
content:
Expand Down Expand Up @@ -450,6 +446,14 @@ paths:
$ref: '#/components/schemas/Error'
components:
schemas:
QueryResult:
type: object
properties:
result:
type: array
nullable: true
items:
type: object
NQuads:
type: "string"
format: "binary"
Expand Down
18 changes: 17 additions & 1 deletion server/http/api_v2.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,20 @@ func (api *APIv2) handleForRequest(r *http.Request) (*graph.Handle, error) {
return HandleForRequest(api.h, api.wtyp, api.wopt, r)
}

// writeResponse represents the response received for a successful write
type writeResponse struct {
Result string `json:"result"`
Count int `json:"count"`
}

// newWriteResponse creates a new WriteResponse for given count of quads written
func newWriteResponse(count int) writeResponse {
return writeResponse{
Result: fmt.Sprintf("Successfully wrote %d quads.", count),
Count: count,
}
}

func (api *APIv2) ServeWrite(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
if api.ro {
Expand Down Expand Up @@ -229,7 +243,9 @@ func (api *APIv2) ServeWrite(w http.ResponseWriter, r *http.Request) {
return
}
w.Header().Set(hdrContentType, contentTypeJSON)
fmt.Fprintf(w, `{"result": "Successfully wrote %d quads.", "count": %d}`+"\n", n, n)
response := newWriteResponse(n)
encoder := json.NewEncoder(w)
encoder.Encode(response)
}

func (api *APIv2) ServeDelete(w http.ResponseWriter, r *http.Request) {
Expand Down
85 changes: 56 additions & 29 deletions server/http/api_v2_test.go
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
package cayleyhttp

import (
"bytes"
"encoding/json"
"io"
"net/http"
"net/http/httptest"
"sort"
"testing"

"github.com/cayleygraph/cayley/client"
"github.com/cayleygraph/cayley/graph"
"github.com/cayleygraph/cayley/graph/graphtest"
"github.com/cayleygraph/cayley/graph/memstore"
"github.com/cayleygraph/cayley/writer"
"github.com/cayleygraph/quad"
"github.com/cayleygraph/quad/jsonld"
"github.com/stretchr/testify/require"
)

Expand All @@ -21,46 +24,70 @@ func makeHandle(t testing.TB, quads ...quad.Quad) *graph.Handle {
return &graph.Handle{qs, wr}
}

func makeServerV2(t testing.TB, quads ...quad.Quad) (string, func()) {
func makeServerV2(t testing.TB, quads ...quad.Quad) *APIv2 {
h := makeHandle(t, quads...)
return NewAPIv2(h)
}

func writeQuads(q []quad.Quad, w io.Writer) error {
writer := jsonld.NewWriter(w)
reader := quad.NewReader(quads)
_, err := quad.Copy(writer, reader)
writer.Close()
return err
}

var mime = quad.FormatByName("jsonld").Mime[0]

api2 := NewAPIv2(h)
srv := httptest.NewServer(api2)
addr := srv.Listener.Addr()
return "http://" + addr.String(), func() {
srv.Close()
h.Close()
}
var quads = []quad.Quad{
quad.MakeIRI("http://example.com/bob", "http://example.com/likes", "http://example.com/alice", ""),
quad.MakeIRI("http://example.com/alice", "http://example.com/likes", "http://example.com/bob", ""),
}

func TestV2Write(t *testing.T) {
addr, closer := makeServerV2(t)
defer closer()
api := makeServerV2(t)
buf := bytes.NewBuffer(nil)

quads := graphtest.MakeQuadSet()
cli := client.New(addr)
qw, err := cli.QuadWriter()
err := writeQuads(quads, buf)
require.NoError(t, err)
defer qw.Close()
n, err := quad.Copy(qw, quad.NewReader(quads))
require.NoError(t, err)
require.Equal(t, int(len(quads)), n)
err = qw.Close()

req, err := http.NewRequest(http.MethodGet, prefix+"/write", buf)
require.NoError(t, err)
req.Header.Set(hdrContentType, mime)

rr := httptest.NewRecorder()
handler := http.HandlerFunc(api.ServeWrite)
handler.ServeHTTP(rr, req)

require.Equal(t, rr.Code, http.StatusOK, rr.Body.String())

expectedResponse := newWriteResponse(len(quads))

var response writeResponse
json.Unmarshal(rr.Body.Bytes(), &response)

require.Equal(t, expectedResponse, response)
}

func TestV2Read(t *testing.T) {
expect := graphtest.MakeQuadSet()
addr, closer := makeServerV2(t, expect...)
defer closer()
api := makeServerV2(t, quads...)
buf := bytes.NewBuffer(nil)

cli := client.New(addr)
qr, err := cli.QuadReader()
req, err := http.NewRequest(http.MethodGet, prefix+"/read", buf)
require.NoError(t, err)
defer qr.Close()
quads, err := quad.ReadAll(qr)
req.Header.Set(hdrAccept, mime)

rr := httptest.NewRecorder()
handler := http.HandlerFunc(api.ServeRead)
handler.ServeHTTP(rr, req)

require.Equal(t, rr.Code, http.StatusOK, rr.Body.String())

reader := jsonld.NewReader(rr.Body)
receivedQuads, err := quad.ReadAll(reader)
require.NoError(t, err)
sort.Sort(quad.ByQuadString(receivedQuads))
sort.Sort(quad.ByQuadString(quads))
sort.Sort(quad.ByQuadString(expect))
require.Equal(t, expect, quads)
require.Equal(t, quads, receivedQuads)

}

0 comments on commit 80bd8af

Please sign in to comment.