Eve: Building RESTful APIs with MongoDB and Flask Transcripts
Chapter: Schema definitions and validation
Lecture: Data-relations and embedded resource serialization
0:01 One very special rule you have in your Eve arsenal is data relations.
0:05 Now, data relations don't really belong to the Mongo world,
0:10 in Mongo, you tend to use the subdocuments and sublists whenever possible
0:14 but there are situations where it still makes sense
0:17 to split data into different collections.
0:20 When you do that, Mongo doesn't offer you
0:23 a join feature like the SQL databases do.
0:27 You can achieve a similar result with the aggregation framework
0:31 which is also supported by Eve, by the way,
0:34 but the simple join between two documents
0:38 stored in different collections— that's a no-go.
0:41 Eve, however offers support for what we call embedded resource serialization.
0:48 It allows a client to request the reference of document
0:53 which are on different collections
0:55 to be returned as a subdocument.
0:58 So yes, with Eve data relations you're basically getting a join feature for free.
1:07 This is useful because this way
1:10 the client only has to perform one request to the remote server
1:14 whereas it will need two different ones.
1:18 To illustrate how data relations work in Eve I defined a new endpoint
1:23 let me close the people endpoint definition, and here we have works,
1:27 works has a schema and most of these fields are standard ones,
1:32 like title, which is a required string and description which is a string.
1:37 Let me close this one, let's look at owner.
1:41 Owner is of type objectid, it is required, and it also has a data relation.
1:49 So the reference at the resource is people
1:54 which means that an objectid in the owner field
1:59 is a reference to a document in the people collection with the same objectid.
2:05 It is also embeddable, which means that
2:08 clients are allowed to request as you can see in this example, here,
2:14 they are allowed to request the owner of this work to be embedded.
2:22 So let's go back to Postman and see these in action.
2:26 At the people endpoint that we have a number of authors,
2:30 let's take John Doe, for example, and copy his own id here.
2:35 Let's go and check the works endpoint.
2:40 It is empty, of course, let's try to post a new work,
2:46 something like a title, which might be My New Book,
2:55 description we'll skip it since it is not required.
3:00 but we want to add an owner
3:06 and the owner is going to be the id to John Doe,
3:09 It should be set, let's try this one, created, great.
3:14 So we got this in, let's try to hit the endpoint for this work,
3:25 Sorry, I need to perform a get request here,
3:28 Okay, my new book, and as you can see, owner is, off course, an id,
3:35 which is nice, useful, but a client now would need to go back to the remote server
3:42 and perform a request to the people endpoint for this author,
3:50 if it wanted to know who is the owner of this book or author.
3:56 So, what we can do here is, let me strip this a little bit,
4:03 is do something different.
4:12 So what I'm doing here is tell the API
4:15 hey send me this work here with this id,
4:19 but return the owner as an embedded document.
4:26 And here we go, as you can see now we get the title
4:30 and the owner is not a simple id anymore
4:33 it is actually a subdocument with the data coming from the people collection.
4:40 If I go back to the endpoint I can perform an embedded request here as well.
4:50 Now we only have one item in this collection
4:52 but as you can see here, if I had more than one work in the collection,
4:59 every single one would have a subdocument for the owner field.
5:04 Now this is a powerful and useful feature,
5:07 but it comes at a cost of course,
5:09 while the server is only receiving one request from the client
5:14 it is actually performing two requests on the database itself, as you can imagine
5:20 so when an embedded request comes in,
5:23 what happens is that Eve first retrieves the works document
5:28 and then goes and retrieves the owner
5:31 and builds an embedded document on the fly
5:35 before providing it back to the client.
5:38 Performance takes a hit here and you have to decide if it is worth it,
5:44 especially when clients are performing requests at the resource endpoint
5:49 like this one here, if we had, 1000 works in this collection
5:56 and every single document would require a double lookup
6:01 that would surely have a significant impact on your performance.
6:06 So you only want to enable embedding for fields where it really makes sense,
6:12 this is why it doesn't come by default,
6:15 you actually have to switch embeddable to true
6:18 if you want a client to be able to elevate a request to an embedded request.
6:24 Furthermore, you can disable embedding at any point
6:29 by simply setting the embedding to false, it is on by default,
6:39 it doesn't have any real impact until you switch the single fields on
6:44 by setting the embeddable option we saw before,
6:48 but you can switch off embedding totally
6:51 by just setting embedding = false.
6:54 Also, you can keep it enabled here at the global level
6:58 and then at the endpoint level, you can decide that,
7:06 for example, works can't be embedded.
7:12 So if you do these, even if the owner field below
7:17 within the schema is embeddable,
7:19 because of at the resource level,
7:22 embedding has been turned off,
7:24 the embedding request will be ignored.
7:27 Let's try that, let's save this new setting,
7:33 restart the server— oh, there is an error.
7:37 Oh, yes, of course, I'm not in C# here,
7:39 this is Python, so we need to do this, and back the client we go,
7:46 same request, embed query parameters is being ignored,
7:54 and this is because we switched embedding off for the works endpoint
7:59 If we had an embeddable field in the people collection,,
8:04 that one would still work, because by default,
8:06 embedding is enabled at a global level,
8:10 but works again were disabled locally.