While creating the API interface for the activity entity, I needed to display the path to the API file.
I use the Sonata Media Bundle for file management.

src/Entity/Web/AdditionalActivity.php

class AdditionalActivity
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column]
    private ?int $id = null;

    #[ORM\Column]
    #[Assert\NotNull]
    private ?bool $isActive = false;

    #[ORM\Column(length: 255)]
    #[Assert\NotBlank]
    #[Assert\Length(max: 255)]
    #[Groups(['additional-activity:read'])]
    private ?string $title = null;

    #[ORM\ManyToOne]
    #[Groups(['additional-activity:read'])]
    private ?SonataMediaMedia $imageMedia1 = null;

I marked the fields to be serialized with the additional-activity:read group.
My controller is very simple: it is supposed to fetch all the entities and serialize them to JSON.

src/Controller/Api/Web/AdditionalActivityController.php

<?php

namespace App\Controller\Api\Web;

use App\Repository\Web\AdditionalActivityRepository;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;

final class AdditionalActivityController extends AbstractController
{
    #[Route(
        '/api/additional-activities',
        name: 'api_additional_activities',
        methods: ['GET'],
        format: 'json',
    )]
    public function index(
        Request $request,
        AdditionalActivityRepository $additionalActivityRepository,
    ): Response {
        $additionalActivities = $additionalActivityRepository->findAll();


        return $this->json([
            'data' => $additionalActivities,
        ], Response::HTTP_OK, [], [
            'groups' => ['additional-activity:read'],
        ]);
    }
}

Result from API:

{
  "data": [
    {
      "title": "Dodatkowa aktywność 1",
      "imageMedia1": [],
    },
    {
      "title": "Alias et quia qui reprehenderit iure pariatur itaque.",
      "imageMedia1": null,
    },
  ]
}

As we can see, the file path is missing for the imageMedia1 field. We will resolve this issue using a dedicated serializer. To generate the path, I will use the built-in: path function found in the SonataMediaBundle file:
vendor/sonata-project/media-bundle/src/Twig/MediaRuntime.php

The path will be created only for the additional-activity:read group. Additional ones can be added here if necessary.

src/Serializer/MediaSerializer.php

<?php

namespace App\Serializer;

use App\Entity\SonataMediaMedia;
use Sonata\MediaBundle\Twig\MediaRuntime;
use Symfony\Component\DependencyInjection\Attribute\Autowire;
use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerAwareTrait;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;

class MediaSerializer implements NormalizerInterface, NormalizerAwareInterface
{
    use NormalizerAwareTrait;
    private const string ALREADY_CALLED = 'MEDIA_NORMALIZER_ALREADY_CALLED';

    public function __construct(
        #[Autowire(service: 'sonata.media.twig.runtime')]
        private MediaRuntime $mediaRuntime,
    ) {
    }

    /**
     * @return array<string, mixed>
     */
    public function normalize(mixed $object, ?string $format = null, array $context = []): array
    {
        /** @var SonataMediaMedia $object */
        $context[self::ALREADY_CALLED] = true;

        $data = $this->normalizer->normalize($object, $format, $context);

        if (!empty(array_intersect($context['groups'] ?? [], ['additional-activity:read']))) {
            $data['referencePathname'] = $this->mediaRuntime->path($object, 'reference');
        }

        return $data;
    }

    /**
     * @param array<string, mixed> $context
     */
    public function supportsNormalization(mixed $data, ?string $format = null, array $context = []): bool
    {
        if (!$data instanceof SonataMediaMedia) {
            return false;
        }

        // avoid recursion: only call once per object
        if (isset($context[self::ALREADY_CALLED])) {
            return false;
        }

        return true;
    }

    /**
     * @return array<class-string, bool>
     */
    public function getSupportedTypes(?string $format): array
    {
        return [SonataMediaMedia::class => false]; // low memory error when true
    }
}

Result from API:

{
  "data": [
    {
      "title": "Dodatkowa aktywność 1",
      "imageMedia1": {
        "referencePathname": "/uploads/media/additional_activity/0001/01/d5da05061cbc5cda9103114fef87ee3de34175ee.jpg"
      },
    },
    {
      "title": "Alias et quia qui reprehenderit iure pariatur itaque.",
      "imageMedia1": null,
    },
  ]
}