Skip to main content
The image gallery is where couples and guests view all photos uploaded to a wedding event. Photos are stored in AWS S3 and organized by event, with visibility controls to manage which images are displayed. Each event has its own photo gallery containing all images uploaded by the couple and their guests. The gallery displays photos with metadata and provides options for viewing and managing the collection.
Images are stored in Amazon S3, providing scalable, reliable, and cost-effective cloud storage for wedding photos.

Image properties

Each image in the gallery has associated metadata:
@Entity
@Table(name = "images")
public class Image {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ManyToOne
    @JoinColumn(name = "event_id")
    private Event event;

    private String imageKey;

    private boolean isVisible;

    @Column(insertable = false, updatable = false)
    private LocalDateTime createdAt;
}

Core properties

id
Long
Unique identifier for the image
event
Event
The wedding event this image belongs to
imageKey
string
The S3 object key (filename) used to retrieve the image from cloud storage
isVisible
boolean
Controls whether the image is displayed in the gallery. Couples can hide images they don’t want to show.
createdAt
LocalDateTime
Timestamp when the image was uploaded

Retrieving event photos

The gallery displays all photos for a specific event. Users request images by event ID.

Get images endpoint

@GetMapping("{eventID}")
public List<ImageResponse> getAllImagesByEventID(@PathVariable Long eventID) {
    return imageService.getAllImagesByEventID(eventID);
}

Image service

public List<ImageResponse> getAllImagesByEventID(Long eventID) {
    return imageRepository.findByEventId(eventID)
        .stream()
        .map(ImageResponse::fromImage)
        .toList();
}
The retrieval process:
  1. Client requests images for a specific event ID
  2. System queries database for all images associated with that event
  3. Images are converted to response DTOs
  4. List of images is returned with metadata

Image response structure

public class ImageResponse {
    private Long id;
    private String imageKey;
    private boolean isVisible;
    private Long eventId;

    public static ImageResponse fromImage(Image image) {
        return new ImageResponse(
            image.getId(),
            image.getImageKey(),
            image.isVisible(),
            image.getEvent().getId()
        );
    }
}

Example response

[
  {
    "id": 1,
    "imageKey": "wedding-ceremony-001.jpg",
    "isVisible": true,
    "eventId": 5
  },
  {
    "id": 2,
    "imageKey": "reception-dance-042.jpg",
    "isVisible": true,
    "eventId": 5
  }
]
The imageKey corresponds to the object key in S3. Your frontend can construct the full S3 URL using this key to display the images.

AWS S3 integration

All images are stored in Amazon S3, which provides:
  • Scalability: Store unlimited photos without worrying about server storage
  • Reliability: 99.999999999% durability with automatic redundancy
  • Performance: Fast retrieval and serving of images globally
  • Cost-effectiveness: Pay only for storage and bandwidth used

S3 service configuration

@Service
public class S3Service {
    @Autowired
    private S3Client s3Client;

    @Value("${aws.s3.bucket}")
    private String bucketName;

    public void uploadFile(String key, File file) {
        PutObjectRequest request = PutObjectRequest.builder()
            .bucket(bucketName)
            .key(key)
            .build();

        s3Client.putObject(request, file.toPath());
    }
}
The S3 bucket name is configured in application properties. Make sure to set up AWS credentials and configure the correct bucket for your deployment.

Image visibility controls

Couples can control which images appear in the gallery using the isVisible flag. This allows them to curate the photo collection by hiding unwanted images without permanently deleting them.

Visibility use cases

If a guest accidentally uploads an inappropriate or duplicate photo, the couple can hide it from the gallery without deleting it entirely.
Couples can create a curated selection of their favorite photos by hiding less desirable shots while keeping them in storage.
Images can be hidden temporarily and made visible again later, providing flexibility in gallery management.

Default visibility

When images are uploaded, they are set to visible by default:
public ResponseEntity<String> createNewImage(ImageRequest request) {
    Event event = eventRepository.findById(request.getEventId())
        .orElseThrow(() -> new RuntimeException("Event not found"));
    
    Image image = new Image();
    image.setVisible(true);  // Visible by default
    image.setImageKey(request.getFile().getOriginalFilename());
    image.setEvent(event);
    
    imageRepository.save(image);
    return uploadFile(request.getFile());
}
The current implementation sets all uploaded images to visible. In a production system, you may want to implement moderation features or allow couples to review images before making them visible.
Here’s how users typically interact with the image gallery:

Deleting images

Couples and authorized users can permanently delete images from both the database and S3 storage.

Delete endpoint

@DeleteMapping("{imageID}")
public ResponseEntity<String> deleteFile(@PathVariable Long imageID) {
    return imageService.deleteImageByImageID(imageID);
}

Deletion service

public ResponseEntity<String> deleteImageByImageID(Long imageID) {
    Image image = imageRepository.findById(imageID)
        .orElseThrow(() -> new RuntimeException("Event not found"));
    
    imageRepository.deleteById(imageID);
    
    String imageKey = image.getImageKey();
    s3Service.deleteFile(imageKey);
    
    return new ResponseEntity<>(HttpStatus.OK);
}

S3 deletion

public void deleteFile(String key) {
    DeleteObjectRequest request = DeleteObjectRequest.builder()
        .bucket(bucketName)
        .key(key)
        .build();
    
    s3Client.deleteObject(request);
}
The deletion process:
  1. Client requests deletion by image ID
  2. System retrieves image metadata from database
  3. Image record is deleted from database
  4. Image file is deleted from S3 bucket
  5. Success response is returned
Image deletion is permanent and cannot be undone. Both the database record and the S3 file are removed. Consider implementing a soft delete or backup mechanism for production use.

Event-based organization

All images are automatically organized by event, making it easy to browse photos from specific weddings.

Cloud storage

AWS S3 provides reliable, scalable storage that can handle thousands of high-resolution wedding photos.

Visibility controls

Couples can hide images from the gallery without deleting them, allowing for curation and moderation.

Metadata tracking

Each image includes upload timestamp and event association for easy management.

Best practices

Performance optimization: Consider implementing pagination for events with many photos. Loading hundreds of images at once can slow down the gallery.
Image thumbnails: Generate and serve thumbnail versions of images for faster gallery loading, with options to view full-resolution versions.
Lazy loading: Implement lazy loading in the frontend to load images as users scroll, improving initial page load time.
  • Image Upload - How photos are uploaded to the gallery
  • Events - Managing wedding events that contain galleries
  • Authentication - Access control for viewing galleries

Build docs developers (and LLMs) love