Skip to content

Commit 36836ef

Browse files
add missing /collections/{collectionId}/items POST api
* openapi.go: add paramFeatureID
1 parent fdfb738 commit 36836ef

File tree

2 files changed

+117
-11
lines changed

2 files changed

+117
-11
lines changed

internal/api/openapi.go

+104-10
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,76 @@ package api
1414
*/
1515

1616
import (
17+
"encoding/json"
1718
"net/url"
1819

1920
"github.com/CrunchyData/pg_featureserv/internal/conf"
2021
"github.com/getkin/kin-openapi/openapi3"
2122
log "github.com/sirupsen/logrus"
2223
)
2324

25+
func getFeatureExample() map[string]interface{} {
26+
var result map[string]interface{}
27+
var jsonStr = `{"type":"Feature","geometry":{"type":"Point","coordinates":[-70.88461956597838,47.807897059236495]},"properties":{"prop_a":"propA","prop_b":1,"prop_c":"propC","prop_d":1}}`
28+
err := json.Unmarshal([]byte(jsonStr), &result)
29+
if err != nil {
30+
return nil
31+
}
32+
return result
33+
}
34+
35+
var FeatureSchema openapi3.Schema = openapi3.Schema{
36+
Type: "object",
37+
Required: []string{},
38+
Properties: map[string]*openapi3.SchemaRef{
39+
"id": {
40+
Value: &openapi3.Schema{
41+
OneOf: []*openapi3.SchemaRef{
42+
openapi3.NewSchemaRef("", &openapi3.Schema{
43+
Type: "number", Format: "long",
44+
}),
45+
openapi3.NewSchemaRef("", &openapi3.Schema{
46+
Type: "string",
47+
}),
48+
},
49+
},
50+
},
51+
"type": {
52+
Value: &openapi3.Schema{
53+
Type: "string",
54+
Default: "Feature",
55+
},
56+
},
57+
"geometry": {
58+
Value: &openapi3.Schema{
59+
Type: "string", // mandatory to validate the schema
60+
OneOf: []*openapi3.SchemaRef{
61+
openapi3.NewSchemaRef("https://geojson.org/schema/Point.json", &openapi3.Schema{Type: "string"}),
62+
openapi3.NewSchemaRef("https://geojson.org/schema/LineString.json", &openapi3.Schema{Type: "string"}),
63+
openapi3.NewSchemaRef("https://geojson.org/schema/Polygon.json", &openapi3.Schema{Type: "string"}),
64+
openapi3.NewSchemaRef("https://geojson.org/schema/MultiPoint.json", &openapi3.Schema{Type: "string"}),
65+
openapi3.NewSchemaRef("https://geojson.org/schema/MultiLineString.json", &openapi3.Schema{Type: "string"}),
66+
openapi3.NewSchemaRef("https://geojson.org/schema/MultiPolygon.json", &openapi3.Schema{Type: "string"}),
67+
},
68+
},
69+
},
70+
"properties": {
71+
Value: &openapi3.Schema{
72+
Type: "object",
73+
},
74+
},
75+
"bbox": {
76+
Value: &openapi3.Schema{
77+
Type: "array",
78+
MinItems: 4,
79+
MaxItems: openapi3.Uint64Ptr(4),
80+
Items: openapi3.NewSchemaRef("", openapi3.NewFloat64Schema().WithMin(-180).WithMax(180)),
81+
},
82+
},
83+
},
84+
Example: getFeatureExample(),
85+
}
86+
2487
// GetOpenAPIContent returns a Swagger OpenAPI structure
2588
func GetOpenAPIContent(urlBase string) *openapi3.Swagger {
2689

@@ -53,6 +116,16 @@ func GetOpenAPIContent(urlBase string) *openapi3.Swagger {
53116
AllowEmptyValue: false,
54117
},
55118
}
119+
paramFeatureID := openapi3.ParameterRef{
120+
Value: &openapi3.Parameter{
121+
Name: "featureId",
122+
Description: "Id of feature in collection to retrieve data for.",
123+
In: "path",
124+
Required: true,
125+
Schema: &openapi3.SchemaRef{Value: openapi3.NewStringSchema()},
126+
AllowEmptyValue: false,
127+
},
128+
}
56129
paramBbox := openapi3.ParameterRef{
57130
Value: &openapi3.Parameter{
58131
Name: "bbox",
@@ -365,6 +438,36 @@ func GetOpenAPIContent(urlBase string) *openapi3.Swagger {
365438
},
366439
},
367440
},
441+
Post: &openapi3.Operation{
442+
OperationID: "createCollectionFeature",
443+
Parameters: openapi3.Parameters{
444+
&paramCollectionID,
445+
&paramFeatureID,
446+
// TODO keep it for the next evolution
447+
// &paramCrs,
448+
},
449+
RequestBody: &openapi3.RequestBodyRef{
450+
Value: &openapi3.RequestBody{
451+
Description: "Add a new feature",
452+
Required: true,
453+
Content: openapi3.NewContentWithJSONSchema(&FeatureSchema),
454+
},
455+
},
456+
Responses: openapi3.Responses{
457+
"201": &openapi3.ResponseRef{
458+
Value: &openapi3.Response{
459+
Description: "Empty body with location header",
460+
Headers: map[string]*openapi3.HeaderRef{
461+
"location": {
462+
Value: &openapi3.Header{
463+
Description: "Contains a link to access to the new feature data",
464+
},
465+
},
466+
},
467+
},
468+
},
469+
},
470+
},
368471
},
369472
apiBase + "collections/{collectionId}/schema": &openapi3.PathItem{
370473
Summary: "Feature schema for collection",
@@ -399,16 +502,7 @@ func GetOpenAPIContent(urlBase string) *openapi3.Swagger {
399502
OperationID: "getCollectionFeature",
400503
Parameters: openapi3.Parameters{
401504
&paramCollectionID,
402-
&openapi3.ParameterRef{
403-
Value: &openapi3.Parameter{
404-
Name: "featureId",
405-
Description: "Id of feature in collection to retrieve data for.",
406-
In: "path",
407-
Required: true,
408-
Schema: &openapi3.SchemaRef{Value: openapi3.NewStringSchema()},
409-
AllowEmptyValue: false,
410-
},
411-
},
505+
&paramFeatureID,
412506
&paramProperties,
413507
&paramTransform,
414508
&paramCrs,

internal/service/handler_post_test.go

+13-1
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,23 @@ func TestApiContainsCollectionSchemas(t *testing.T) {
4242
util.Assert(t, path != nil, "schema path exists")
4343
util.Equals(t, "Provides access to data representation (schema) for any features in specified collection", path.Description, "schema path present")
4444
util.Equals(t, "getCollectionSchema", path.Get.OperationID, "schema path get present")
45-
util.Equals(t, 2, len(path.Get.Parameters), "schema path get present")
45+
util.Equals(t, 2, len(path.Get.Parameters), "# path")
4646
util.Assert(t, path.Get.Parameters.GetByInAndName("path", "collectionId") != nil, "collectionId path parameter exists")
4747
util.Assert(t, path.Get.Parameters.GetByInAndName("query", "type") != nil, "type query parameter exists")
4848
}
4949

50+
// checks swagger api contains method PATCH for updating a feaure from a specified collection
51+
func TestApiContainsMethodPostFeature(t *testing.T) {
52+
resp := hTest.DoRequest(t, "/api")
53+
body, _ := ioutil.ReadAll(resp.Body)
54+
55+
var v openapi3.Swagger
56+
err := json.Unmarshal(body, &v)
57+
util.Assert(t, err == nil, fmt.Sprintf("%v", err))
58+
59+
util.Equals(t, "createCollectionFeature", v.Paths.Find("/collections/{collectionId}/items").Post.OperationID, "method POST present")
60+
}
61+
5062
// checks collection schema contains valid data description
5163
func TestGetCollectionCreateSchema(t *testing.T) {
5264
path := "/collections/mock_a/schema?type=create"

0 commit comments

Comments
 (0)