Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Content Negotiation #1319

Open
MiltosD opened this issue Oct 16, 2024 · 5 comments
Open

Content Negotiation #1319

MiltosD opened this issue Oct 16, 2024 · 5 comments

Comments

@MiltosD
Copy link

MiltosD commented Oct 16, 2024

Is it possible to return a different response based on the "Accept" header or a query param e.g. ?format=json-ld

@vitalik
Copy link
Owner

vitalik commented Oct 16, 2024

@MiltosD you can create custom renderer

overwrite render method - get Accept header and based on it value serialize response differently

@MiltosD
Copy link
Author

MiltosD commented Oct 16, 2024

The example shows that renderers are applied to the api level

api = NinjaAPI(renderer=MyRenderer())

However the case is in a @api.get() view where I check for the header and decide which renderer (better off, which Schema) to use within the view, for example, if the Accept header is "application/ld+json", then the view response is to be of type MySchemaLD, else MySchema.

@MiltosD
Copy link
Author

MiltosD commented Oct 16, 2024

I ended up with this, not sure if it's a neat approach

@api.get("/person/{pk}/", response=Any)
def get_person(request, pk, format: str = None):
    person = get_object_or_404(Person, pk=pk)
    by_alias = False
    if format == "json-ld":
        schema: Type[Schema] = PersonSchemaLD
        by_alias = True
    else:
        schema: Type[Schema] = PersonSchema
    return schema.from_orm(person).model_dump(
        exclude_unset=True,
        exclude_none=True,
        exclude_defaults=True,
        by_alias=by_alias
    )

It seems to work with /person/1?format=json-ld

@vitalik
Copy link
Owner

vitalik commented Oct 16, 2024

hard to tell - need to see how exactly your json and json-ld are different

@MiltosD
Copy link
Author

MiltosD commented Oct 17, 2024

Well, a json-ld output contains a @context object which is not present in plain json, plus information for the fields, that are relevant to rdf. For example a person might be

plain json

{
  "name": "John Doe",
  "country": "Germany"
}

json-ld

{
  "@context": {
    "ex": "http://example.com",
    "dct": "http://purl.org/dc/terms/"
  },
  "@type": "foaf:Person",
  "foaf:name": "John Doe",
  "ex:country": {
    "@type": "dct:Location",
    "@id": "http://publications.europa.eu/resource/authority/country/DEU"
  }
}

The transformation from country to ex:country is done by using serialization_alias and resolvers

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants