Open diegodelemos opened 4 years ago
To use the REST API, we would have to change the loaders, since the author field is not defined
How exactly do the loaders need to be changed? Is it it just the author
field needs adding to records.marshmallow.json.MetadataSchemaV1
? What kind of field should it be?
Presumably there's also something that needs doing to the deposit form to find and link the authors?
A minimal change to create the record
using the REST API appears to be:
modified my_site/records/marshmallow/json.py
@@ -8,7 +8,7 @@
"""JSON Schemas."""
from invenio_jsonschemas import current_jsonschemas
-from invenio_records_rest.schemas import Nested, StrictKeysMixin
+from invenio_records_rest.schemas import Nested, StrictKeysMixin, RecordMetadataSchemaJSONV1
from invenio_records_rest.schemas.fields import DateString, GenFunction, \
PersistentIdentifier, SanitizedUnicode
from marshmallow import fields, missing, validate
@@ -54,7 +54,7 @@ class ContributorSchemaV1(StrictKeysMixin):
email = fields.Email()
-class MetadataSchemaV1(StrictKeysMixin):
+class MetadataSchemaV1(RecordMetadataSchemaJSONV1):
"""Schema for the record metadata."""
id = PersistentIdentifier()
Which allows creation with:
curl -k --header Content-Type: application/json \
--request POST \
--data {"author": { "$ref": "https://my-site.com/api/resolver/author/1" }, \
"title": "Invenio is awesome", "contributors": [{"name": "Kent, Clark"}], \
"owner": 1}
https://127.0.0.1:5000/api/records/?prettyprint=1
If I'm understanding how this works correctly, StrictKeysMixin
will fail because author
is not defined in MetadataSchemaV1
, while RecordMetadataSchemaJSONV1
just passes along any keys it doesn't recognise.
However, retrieving the record
doesn't include the author
in the REST API:
$ curl -ks https://localhost:5000/api/records/2?prettyprint=1
{
"id": "2",
"links": {
"files": "https://localhost:5000/api/records/2/files",
"self": "https://localhost:5000/api/records/2"
},
"metadata": {
"contributors": [
{
"name": "Kent, Clark"
}
],
"id": "2",
"owner": 1,
"pid": "2",
"title": "Invenio is awesome"
},
"revision": 0,
"updated": "2022-07-11T09:42:17.536711+00:00"
and in the web view, author
is there but it doesn't get resolved:
So, has this just moved the problem onto the mapping? Sticking a print(record)
into record_jsonresolver
, I can see that it is correctly resolving the author
when the record
is retrieved via the REST API, though not through the web interface.
Further investigation reveals that searching for author.name
in /api/records/
works with the above change, it's just the serialisation where it disappears.
I looked into that further, and the author reference does get resolved when access via REST, but marshmallow removes it, I guess because it's not in MetadataSchemaV1
. The web interface doesn't call the resolver at all.
I've been looking at invenio-app-ils
as an example that has links between data models, and I can't see how that handles anything differently, except for the change I suggest above.
Is this the expected behaviour?
I think I have something working, I'm just not sure if it's sensible:
modified my_site/records/config.py
@@ -66,6 +66,7 @@ RECORDS_UI_ENDPOINTS = dict(
route='/records/<pid_value>',
template='records/record.html',
record_class='invenio_records_files.api:Record',
+ view_imp="my_site.records.views:record_view",
),
recid_previewer=dict(
pid_type='recid',
modified my_site/records/marshmallow/json.py
@@ -63,6 +63,7 @@ class MetadataSchemaV1(StrictKeysMixin):
publication_date = DateString()
contributors = Nested(ContributorSchemaV1, many=True, required=True)
owner = fields.Integer()
+ author = fields.Dict()
_schema = GenFunction(
attribute="$schema",
data_key="$schema",
modified my_site/records/views.py
@@ -12,6 +12,7 @@ from os.path import splitext
from flask import Blueprint
from invenio_previewer.proxies import current_previewer
+from invenio_records_ui.views import default_view_method
blueprint = Blueprint(
'my_site_records',
@@ -46,3 +47,6 @@ def select_preview_file(files):
except KeyError:
pass
return selected
+
+def record_view(pid, record, template=None, **kwargs):
+ return default_view_method(pid, record.replace_refs(), template, **kwargs)
Instead of using RecordMetadataSchemaJSONV1
, we still use StrictKeysMixin
, but add a field for the author that's just fields.Dict()
, so we don't need to define its schema. This allows us to both create a record
with an author
reference, and also allows us to view the resolved author
in the record
REST API.
The other half is to add a custom view that just calls the default view but passes record.replace_refs()
which resolves the references.
If this seems like a sensible solution, I'd be happy to make a PR adding this to the tutorial. If not, I'd really appreciate some pointers on how to fix this properly!
Problem Tutorial 11 relies on creating records with references using the
invenio records
CLI. However, Invenio-Records CLI has been remove in version 1.3.0.Solution Modify tutorial to enable the creation of linked records through the REST API.