rest-layer: Embedding of connected resource is broken

Using the rest package, given a resource “as” with a sub-resource “bs”, when fetching “as” with fields=id,bs, all “bs” are included in all entries. Instead, I wold have expected bs to be filtered by the id of the associated a.

Test

using bat which is a Go clone of HTTPie:

----------------------------------------------------------------------
$ bat POST :2015/api/as Authorization:"Bearer ${KEY}" name=n1  
POST /api/as HTTP/1.1
Host: localhost:2015
Accept: application/json
Accept-Encoding: gzip, deflate
Authorization: Bearer XXX
Content-Type: application/json
User-Agent: bat/0.1.0

{"name":"n1"}

HTTP/1.1 201 Created
Last-Modified : Thu, 07 Sep 2017 20:28:37 GMT
Server : Caddy
Content-Length : 45
Content-Location : /as/ObjectIdHex("59b1abf5cee0fb0001ea732e")
Content-Type : application/json
Date : Thu, 07 Sep 2017 20:28:37 GMT
Etag : "5efa3a3f0f355cef35d7ca2464d4836d"

{
  "id": "59b1abf5cee0fb0001ea732e",
  "name": "n1"
}

----------------------------------------------------------------------
$ bat POST :2015/api/as Authorization:"Bearer ${KEY}" name=n2
POST /api/as HTTP/1.1
Host: localhost:2015
Accept: application/json
Accept-Encoding: gzip, deflate
Authorization: Bearer XXX
Content-Type: application/json
User-Agent: bat/0.1.0

{"name":"n2"}

HTTP/1.1 201 Created
Etag : "9e969caf8cabb3303886ca7fce114668"
Last-Modified : Thu, 07 Sep 2017 20:28:40 GMT
Server : Caddy
Content-Length : 45
Content-Location : /as/ObjectIdHex("59b1abf8cee0fb0001ea732f")
Content-Type : application/json
Date : Thu, 07 Sep 2017 20:28:40 GMT


{
  "id": "59b1abf8cee0fb0001ea732f",
  "name": "n2"
}

----------------------------------------------------------------------
$ bat POST :2015/api/as/59b1abf5cee0fb0001ea732e/bs Authorization:"Bearer ${KEY}" name=b1
POST /api/as/59b1abf5cee0fb0001ea732e/bs HTTP/1.1
Host: localhost:2015
Accept: application/json
Accept-Encoding: gzip, deflate
Authorization: Bearer XXX
Content-Type: application/json
User-Agent: bat/0.1.0

{"name":"b1"}

HTTP/1.1 201 Created
Last-Modified : Thu, 07 Sep 2017 20:29:28 GMT
Server : Caddy
Content-Length : 76
Content-Location : /as/59b1abf5cee0fb0001ea732e/bs/ObjectIdHex("59b1ac28cee0fb0001ea7330")
Content-Type : application/json
Date : Thu, 07 Sep 2017 20:29:28 GMT
Etag : "30cc6d167d31d99716999530fea24a67"

{
  "a": "59b1abf5cee0fb0001ea732e",
  "id": "59b1ac28cee0fb0001ea7330",
  "name": "b1"
}

----------------------------------------------------------------------
$ bat POST :2015/api/as/59b1abf5cee0fb0001ea732e/bs Authorization:"Bearer ${KEY}" name=b2
POST /api/as/59b1abf5cee0fb0001ea732e/bs HTTP/1.1
Host: localhost:2015
Accept: application/json
Accept-Encoding: gzip, deflate
Authorization: Bearer XXX
Content-Type: application/json
User-Agent: bat/0.1.0

{"name":"b2"}

HTTP/1.1 201 Created
Content-Type : application/json
Date : Thu, 07 Sep 2017 20:29:44 GMT
Etag : "61887b89a9bcc295760b5c3ec922479b"
Last-Modified : Thu, 07 Sep 2017 20:29:44 GMT
Server : Caddy
Content-Length : 76
Content-Location : /as/59b1abf5cee0fb0001ea732e/bs/ObjectIdHex("59b1ac38cee0fb0001ea7331")

{
  "a": "59b1abf5cee0fb0001ea732e",
  "id": "59b1ac38cee0fb0001ea7331",
  "name": "b2"
}

----------------------------------------------------------------------
$ bat GET :2015/api/as Authorization:"Bearer ${KEY}" fields=id,bs                                               :(
GET /api/as?fields=id%2Cbs HTTP/1.1
Host: localhost:2015
Accept: application/json
Accept-Encoding: gzip, deflate
Authorization: Bearer XXX
User-Agent: bat/0.1.0

HTTP/1.1 200 OK
Content-Type : application/json
Date : Thu, 07 Sep 2017 20:30:20 GMT
Server : Caddy
X-Total : 2
Content-Length : 477

[
  {
    "_etag": "5efa3a3f0f355cef35d7ca2464d4836d",
    "bs": [
      {
        "a": "59b1abf5cee0fb0001ea732e",
        "id": "59b1ac28cee0fb0001ea7330",
        "name": "b1"
      },
      {
        "a": "59b1abf5cee0fb0001ea732e",
        "id": "59b1ac38cee0fb0001ea7331",
        "name": "b2"
      }
    ],
    "id": "59b1abf5cee0fb0001ea732e"
  },
  {
    "_etag": "9e969caf8cabb3303886ca7fce114668",
    "bs": [
      {
        "a": "59b1abf5cee0fb0001ea732e",
        "id": "59b1ac28cee0fb0001ea7330",
        "name": "b1"
      },
      {
        "a": "59b1abf5cee0fb0001ea732e",
        "id": "59b1ac38cee0fb0001ea7331",
        "name": "b2"
      }
    ],
    "id": "59b1abf8cee0fb0001ea732f"
  }
]

Schema

	rsc := index.Bind("as", schema.Schema{
		Fields: schema.Fields{
			"id": mongo.ObjectIDField,
			"name": {
				Description: "Human readable entity name.",
				Required:    true,
				Filterable:  true,
				Sortable:    true,
				Validator:   &schema.String{},
			},
		},
	},
		mongo.NewHandler(session, "", "a"),
		resource.Conf{
			AllowedModes:           resource.ReadWrite,
			PaginationDefaultLimit: paginationLimit,
		},
	)
	rsc.Bind("bs", "a", schema.Schema{
		Fields: schema.Fields{
			"id": mongo.ObjectIDField,
			"name": {
				Description: "Human readable entity name.",
				Required:    true,
				Filterable:  true,
				Sortable:    true,
				Validator:   &schema.String{},
			},
			"a": {
				Required:   true,
				Filterable: true,
				Sortable:   true,
				Validator:  &schema.Reference{Path: "as"},
			},
		},
	},
		mongo.NewHandler(session, "", "b"),
		resource.Conf{
			AllowedModes:           resource.ReadWrite,
			PaginationDefaultLimit: paginationLimit,
		},
	)

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Comments: 16 (6 by maintainers)

Commits related to this issue

Most upvoted comments

I have some suggestions for (mostly internal) refactoring of resource embedding btw, but I will raise that in a separate ticket.

The connection is there here: https://sourcegraph.com/github.com/rs/rest-layer@b0185e617e9718fea09957f10126b020d04bc033/-/blob/resource/resource.go#L145-146

Actually you’re right. We fully manage the connection in the index so we can safely add this field.