Skip to content

Conversation

@aaronjae22
Copy link
Collaborator

get_json_ld() in Models and Serializers

Model-Level get_json_ld

The get_json_ld method defined on our models is intended to directly access and return JSON-LD data from the model’s instance. This is useful for:

  • Providing LOLA-compliant JSON-LD when working within the model itself.
  • Accessing JSON-LD representations in Python scripts or custom views without involving serializers.
  • Ensuring that the model is self-contained and capable of defining its representation independent of any external tools.

Serializer-Level get_json_ld

The get_json_ld method implemented in a serializer is tailored for API responses. It serializes model data and outputs the JSON-LD representation as part of the API response. This is beneficial because:

  • It integrates cleanly into DRF and works alongside other serializer fields.
  • It allows us to customize the output using the serializer context (e.g., request, user, additional parameters).
from rest_framework import serializers
from .models import Actor, Note, Activity, PortabilityOutbox
from .mixins import JSONLDSerializerMixin

class ActorSerializer(JSONLDSerializerMixin, serializers.ModelSerializer):
    json_ld = serializers.SerializerMethodField()

    class Meta:
        model = Actor
        fields = ['id', 'json_ld']

Closes #9

Mixin

To avoid duplicating the get_json_ld logic, we use a reusable JSONLDSerializerMixin. This mixin will dynamically add a json_ld field to any serializer by calling the model’s get_json_ld method.

from rest_framework import serializers

# Mixin to dynamically add a 'json_ld' field to a serializer.
# It assumes the model has a 'get_json_ld' method.
class JSONLDSerializerMixin:
    json_ld = serializers.SerializerMethodField()

    def get_json_ld(self, obj):
        return obj.get_json_ld()

Closes #18

API Endpoints and Views

Following comments made in #10, we reorganized API Endpoints and Views but also Outbox was added.

Actor

ID: 1, username="alice"

Activities

ID: 2, type="Create", note=Note(ID: 5), actor=Actor(ID: 1)
ID: 3, type="Create", note=Note(ID: 6), actor=Actor(ID: 1)

Notes

ID: 5, content="This is Note 1", actor=Actor(ID: 1)
ID: 6, content="This is Note 2", actor=Actor(ID: 1)

PortabilityOutbox

ID: 4, actor=Actor(ID: 1), activities=[2, 3]

API Response for /api/actors/4/outbox/

The PortabilityOutboxSerializer will call the model’s get_json_ld() method, and the response will look like this:

{
    "id": 4,
    "actor": "alice",
    "json_ld": {
        "@context": "https://www.w3.org/ns/activitystreams",
        "type": "OrderedCollection",
        "id": "https://example.com/users/alice/outbox",
        "totalItems": 2,
        "items": [
            {
                "@context": "https://www.w3.org/ns/activitystreams",
                "type": "Create",
                "id": "https://example.com/activities/2",
                "actor": "https://example.com/users/alice",
                "published": "2024-12-08T12:00:00Z",
                "object": "https://example.com/notes/5"
            },
            {
                "@context": "https://www.w3.org/ns/activitystreams",
                "type": "Create",
                "id": "https://example.com/activities/3",
                "actor": "https://example.com/users/alice",
                "published": "2024-12-08T12:01:00Z",
                "object": "https://example.com/notes/6"
            }
        ]
    }
}

Closes #10

Explanation of each endpoint and view

1. Actor Endpoint

  1. Inspecting an Actor: Allows API clients to fetch details about an Actor, including their LOLA-compliant JSON-LD representation.
  2. Exporting Account Data: Since LOLA focuses on account portability, this endpoint also returns a full exportable representation of the Actor’s data.

GET /api/actors/1/

{
    "id": 1,
    "username": "alice",
    "full_name": "Alice Example",
    "json_ld": {
        "@context": [
            "https://www.w3.org/ns/activitystreams",
            "https://swicg.github.io/activitypub-data-portability/lola.jsonld"
        ],
        "type": "Person",
        "id": "https://example.com/users/alice",
        "preferredUsername": "alice",
        "name": "Alice Example"
    }
}

2. PortabilityOutbox Endpoint

  1. Listing all activities associated with an Actor.
  2. Providing an OrderedCollection of activities in LOLA-compliant JSON-LD format.

GET /api/actors/1/outbox/

{
    "id": 1,
    "actor": "alice",
    "json_ld": {
        "@context": "https://www.w3.org/ns/activitystreams",
        "type": "OrderedCollection",
        "id": "https://example.com/users/alice/outbox",
        "totalItems": 2,
        "items": [
            {
                "type": "Create",
                "id": "https://example.com/activities/1",
                "actor": "https://example.com/users/alice",
                "object": "https://example.com/notes/1"
            },
            {
                "type": "Create",
                "id": "https://example.com/activities/2",
                "actor": "https://example.com/users/alice",
                "object": "https://example.com/notes/2"
            }
        ]
    }
}

3. Deactivate Account Endpoint

The deactivate account view allows staff users or internal logic to deactivate an Actor account.

This is intended for administrative purposes and is not required to be exposed as an API endpoint. Instead, it is implemented as a regular Django view.

  • Provides a way to administratively disable an account.
  • This can be helpful to prevent misuse during testing or limit access.

POST /api/actors/1/deactivate/

4. Trigger Account

  • The Trigger Account functionality allows an implementer to trigger the server to copy an account from another server.
  • This could involve pulling the Actor’s data and importing it.

Implementers use this to test the account portability workflow.

5. Report Activity

  • The Report Activity view allows implementers to report on the success or failure of account portability operations.
  • It could log what activities were copied correctly and what failed.

It helps debug and document the portability process for implementers.

Summary Table of Views

View Purpose Type Endpoint
ActorDetailView Retrieve an Actor’s details and LOLA-compliant JSON-LD. API View /api/actors/int:pk/
PortabilityOutboxView List all activities (OrderedCollection) performed by an Actor. API View /api/actors/int:pk/outbox/
Deactivate Account Deactivate an Actor account for admin/staff usage. Regular View /api/actors/int:actor_id/deactivate/
Trigger Account Trigger copying of an account from another server. Regular View /trigger-account/
Report Activity Report on the results of account portability testing (success/failure). Regular View /report-activity/

Testing the Endpoint

Actor Request:

GET /api/actors/4/

image

Actor’s Outbox Request

GET /api/actors/4/outbox/

image

@aaronjae22 aaronjae22 added the enhancement New feature or request label Dec 10, 2024
@aaronjae22 aaronjae22 self-assigned this Dec 10, 2024
@aaronjae22 aaronjae22 merged commit 3686a63 into main Dec 10, 2024
@aaronjae22 aaronjae22 deleted the core-setup branch April 2, 2025 16:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Create mixin Build API endpoints Create Serializers for translating data for API communication

1 participant