Skip to content

Commit

Permalink
Create new HTTP resource for namespace rules (cayleygraph#925)
Browse files Browse the repository at this point in the history
The resource supports getting all registered rules and registering a rule
  • Loading branch information
iddan authored Apr 9, 2020
1 parent 46f4cfd commit d398bea
Show file tree
Hide file tree
Showing 3 changed files with 149 additions and 3 deletions.
44 changes: 44 additions & 0 deletions docs/api/swagger.yml
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,50 @@ paths:
application/json:
schema:
$ref: "#/components/schemas/Error"
/api/v2/namespace-rules:
get:
tags:
- "data"
summary: "Reads all namespace rules from the database"
description: ""
operationId: "getNamespaceRules"
responses:
200:
description: "Success"
content:
"application/json":
schema:
type: "array"
items:
type: "object"
properties:
prefix:
description: "Prefix of the namespace"
type: "string"
namespace:
description: "The namespace prefixed"
type: "string"
default:
description: "Unexpected error"
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
post:
tags:
- "data"
summary: "Registers new namespace rule to the database"
description: ""
operationId: "registerNamespaceRule"
responses:
201:
description: "Success"
default:
description: "Unexpected error"
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/gephi/gs:
get:
tags:
Expand Down
54 changes: 54 additions & 0 deletions server/http/api_v2.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import (
// Writer is imported for writers to be registered
_ "github.com/cayleygraph/cayley/writer"
"github.com/cayleygraph/quad"
"github.com/cayleygraph/quad/voc"
)

const (
Expand Down Expand Up @@ -584,3 +585,56 @@ func (api *APIv2) ServeQuery(w http.ResponseWriter, r *http.Request) {
}
writeResults(w, out)
}

// NamespaceRule defines a prefix for a namespace when prepended to the suffix of a compact IRI, results in an IRI.
// For example rdfs is a prefix for the namespace http://www.w3.org/2000/01/rdf-schema#.
type NamespaceRule struct {
Prefix string `json:"prefix"`
Namespace string `json:"namespace"`
}

// getNamespaceRules returns all the registered rules
func getNamespaceRules() []NamespaceRule {
var rules []NamespaceRule
for _, n := range voc.List() {
rules = append(rules, NamespaceRule{
Prefix: strings.TrimSuffix(n.Prefix, ":"),
Namespace: n.Full,
})
}
return rules
}

// serveGetNamespaceRules responds with all the registered rules encoded to JSON
func serveGetNamespaceRules(w http.ResponseWriter) {
rules := getNamespaceRules()
encoder := json.NewEncoder(w)
w.Header().Set(hdrContentType, contentTypeJSON)
w.WriteHeader(http.StatusOK)
encoder.Encode(rules)
}

// serveGetNamespaceRules registers received rule encoded in JSON
func servePostNamespaceRules(w http.ResponseWriter, r *http.Request) {
var rule NamespaceRule
decoder := json.NewDecoder(r.Body)
decoder.Decode(&rule)
voc.RegisterPrefix(rule.Prefix, rule.Namespace)
w.WriteHeader(http.StatusCreated)
}

// ServeNamespaceRules serves requests for the namespace rules resource.
// The resource supports getting all registered rules and registering a rule.
// The resource wraps the quad/voc module.
func (api *APIv2) ServeNamespaceRules(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case http.MethodGet:
serveGetNamespaceRules(w)
return
case http.MethodPost:
servePostNamespaceRules(w, r)
return
default:
jsonResponse(w, http.StatusMethodNotAllowed, nil)
}
}
54 changes: 51 additions & 3 deletions server/http/api_v2_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ func TestV2Write(t *testing.T) {
handler := http.HandlerFunc(api.ServeWrite)
handler.ServeHTTP(rr, req)

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

expectedResponse := newWriteResponse(len(quads))

Expand All @@ -87,7 +87,7 @@ func TestV2Read(t *testing.T) {
handler := http.HandlerFunc(api.ServeRead)
handler.ServeHTTP(rr, req)

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

reader := jsonld.NewReader(rr.Body)
receivedQuads, err := quad.ReadAll(reader)
Expand All @@ -111,5 +111,53 @@ func TestV2Delete(t *testing.T) {
handler := http.HandlerFunc(api.ServeDelete)
handler.ServeHTTP(rr, req)

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

func TestV2GetNamespaceRules(t *testing.T) {
api := makeServerV2(t)
buf := bytes.NewBuffer(nil)
req, err := http.NewRequest(http.MethodGet, prefix+"/namespace-rules", buf)
require.NoError(t, err)
rr := httptest.NewRecorder()
handler := http.HandlerFunc(api.ServeNamespaceRules)
handler.ServeHTTP(rr, req)
var rules []NamespaceRule
err = json.Unmarshal(rr.Body.Bytes(), &rules)
require.NoError(t, err)
require.Equal(t, http.StatusOK, rr.Code)
require.Equal(t, contentTypeJSON, rr.Header().Get(hdrContentType))
require.NotEmpty(t, rules)
}

func TestV2PostNamespaceRules(t *testing.T) {
api := makeServerV2(t)
rule := NamespaceRule{
Prefix: "foaf",
Namespace: "http://xmlns.com/foaf/0.1/",
}
buf := bytes.NewBuffer(nil)
encoder := json.NewEncoder(buf)
encoder.Encode(rule)
req, err := http.NewRequest(http.MethodPost, prefix+"/namespace-rules", buf)
require.NoError(t, err)
rr := httptest.NewRecorder()
handler := http.HandlerFunc(api.ServeNamespaceRules)
handler.ServeHTTP(rr, req)
require.NoError(t, err)
require.Equal(t, http.StatusCreated, rr.Code)
require.Empty(t, rr.Body.Bytes())

// Check effect
req, err = http.NewRequest(http.MethodGet, prefix+"/namespace-rules", buf)
require.NoError(t, err)
rr = httptest.NewRecorder()
handler = http.HandlerFunc(api.ServeNamespaceRules)
handler.ServeHTTP(rr, req)
var rules []NamespaceRule
err = json.Unmarshal(rr.Body.Bytes(), &rules)
require.NoError(t, err)
require.Equal(t, http.StatusOK, rr.Code)
require.Equal(t, contentTypeJSON, rr.Header().Get(hdrContentType))
require.Contains(t, rules, rule)
}

0 comments on commit d398bea

Please sign in to comment.