Adds room response options

Introduces response options for room-related API calls, allowing clients to specify which fields to include and which properties to expand.

This change provides more control over the data returned by the API,
reducing payload size and improving performance.
It also fixes an issue where the frontend was not able to request only the fields needed for specific components.
This commit is contained in:
CSantosM 2026-02-06 18:32:06 +01:00
parent 1c85eaa364
commit eacd629006
9 changed files with 77 additions and 35 deletions

View File

@ -0,0 +1,23 @@
import { MeetRoomCollapsibleProperties, MeetRoomField } from '@openvidu-meet/typings';
/**
* Options for configuring the response MeetRoom REST API object
*/
export interface MeetRoomServerResponseOptions {
/**
* Array of fields to include in the response.
* If not specified, all fields are included.
*/
fields?: MeetRoomField[];
/**
* Array of collapsed properties to expand in the response.
* If not specified, no collapsed properties are expanded.
*
*/
collapse?: MeetRoomCollapsibleProperties[];
/**
* Whether to check permissions for the room.
* If true, sensitive properties will be removed from the response if the requester does not have permission to view them.
*/
applyPermissionFiltering?: boolean;
}

View File

@ -11,7 +11,6 @@ import {
MeetRoomFilters,
MeetRoomMemberPermissions,
MeetRoomOptions,
MeetRoomResponseOptions,
MeetRoomRoles,
MeetRoomRolesConfig,
MeetRoomStatus,
@ -37,6 +36,7 @@ import {
OpenViduMeetError
} from '../models/error.model.js';
import { MeetRoomServerResponseOptions } from '../models/room-response.js';
import { RoomMemberRepository } from '../repositories/room-member.repository.js';
import { RoomRepository } from '../repositories/room.repository.js';
import { FrontendEventService } from './frontend-event.service.js';
@ -73,13 +73,13 @@ export class RoomService {
* Creates an OpenVidu Meet room with the specified options.
*
* @param {MeetRoomOptions} roomOptions - The options for creating the OpenVidu room.
* @param {MeetRoomResponseOptions} responseOpts - Options for controlling the response format (fields, collapse)
* @param {MeetRoomServerResponseOptions} responseOpts - Options for controlling the response format (fields, collapse)
* @returns {Promise<MeetRoom>} A promise that resolves to the created OpenVidu room.
*
* @throws {Error} If the room creation fails.
*
*/
async createMeetRoom(roomOptions: MeetRoomOptions, responseOpts?: MeetRoomResponseOptions): Promise<MeetRoom> {
async createMeetRoom(roomOptions: MeetRoomOptions, responseOpts?: MeetRoomServerResponseOptions): Promise<MeetRoom> {
const { roomName, autoDeletionDate, autoDeletionPolicy, config, roles, anonymous } = roomOptions;
const { collapse, fields } = responseOpts || {};
@ -422,7 +422,7 @@ export class RoomService {
* - applyPermissionFiltering: Whether to check permissions for the room and remove sensitive properties if the requester doesn't have access
* @returns A promise that resolves to an {@link MeetRoom} object
*/
async getMeetRoom(roomId: string, responseOpts?: MeetRoomResponseOptions): Promise<MeetRoom> {
async getMeetRoom(roomId: string, responseOpts?: MeetRoomServerResponseOptions): Promise<MeetRoom> {
const { collapse, applyPermissionFiltering, fields } = responseOpts || {};
let room = await this.roomRepository.findByRoomId(roomId, fields);

View File

@ -147,7 +147,10 @@ export class MeetingLobbyService {
this._state.update((state) => ({ ...state, roomId }));
const [room] = await Promise.all([
this.roomService.getRoom(roomId),
this.roomService.getRoom(roomId, {
fields: ['roomName', 'status', 'config'],
expand: ['config']
}),
this.setBackButtonText(),
this.checkForRecordings(),
this.initializeParticipantName()

View File

@ -20,7 +20,9 @@ export const checkEditableRoomGuard: CanActivateFn = async (route) => {
}
try {
const room = await roomService.getRoom(roomId);
const room = await roomService.getRoom(roomId, {
fields: ['status']
});
if (room.status === MeetRoomStatus.ACTIVE_MEETING) {
console.warn(`Cannot edit room ${roomId} - active meeting in progress`);

View File

@ -0,0 +1,17 @@
import { MeetRoomExpandableProperties, MeetRoomField } from '@openvidu-meet/typings';
/**
* Options for configuring the response MeetRoom REST API object
*/
export interface MeetRoomClientResponseOptions {
/**
* Array of fields to include in the response.
* If not specified, all fields are included.
*/
fields?: MeetRoomField[];
/**
* Array of expandable properties to expand in the response.
* If not specified, expandable properties will not be expanded.
*/
expand?: MeetRoomExpandableProperties[];
}

View File

@ -90,7 +90,10 @@ export class RoomWizardComponent implements OnInit {
if (!this.roomId) return;
try {
const { roomName, autoDeletionDate, config } = await this.roomService.getRoom(this.roomId);
const { roomName, autoDeletionDate, config } = await this.roomService.getRoom(this.roomId, {
fields: ['roomName', 'autoDeletionDate', 'config'],
expand: ['config']
});
this.existingRoomData = { roomName, autoDeletionDate, config };
if (this.existingRoomData) {
this.isBasicCreation.set(false);
@ -131,7 +134,7 @@ export class RoomWizardComponent implements OnInit {
async createRoomBasic(roomName?: string) {
try {
// Create room with basic config including e2ee: false (default settings)
const { accessUrl } = await this.roomService.createRoom({ roomName });
const { accessUrl } = await this.roomService.createRoom({ roomName }, { fields: ['accessUrl'] });
// Extract the path and query parameters from the moderator URL and navigate to it
const url = new URL(accessUrl);
@ -162,7 +165,7 @@ export class RoomWizardComponent implements OnInit {
this.notificationService.showSnackbar('Room updated successfully');
} else {
// Create new room
const { accessUrl } = await this.roomService.createRoom(roomOptions);
const { accessUrl } = await this.roomService.createRoom(roomOptions, { fields: ['accessUrl'] });
// Extract the path and query parameters from the moderator URL and navigate to it
const url = new URL(accessUrl);

View File

@ -148,7 +148,8 @@ export class RoomsComponent implements OnInit {
maxItems: 50,
nextPageToken: !refresh ? this.nextPageToken : undefined,
sortField: filters.sortField,
sortOrder: filters.sortOrder
sortOrder: filters.sortOrder,
fields: ['roomId', 'roomName', 'status', 'creationDate', 'accessUrl', 'autoDeletionDate']
};
// Apply room ID filter if provided

View File

@ -14,6 +14,7 @@ import {
import { ILogger, LoggerService } from 'openvidu-components-angular';
import { FeatureConfigurationService } from '../../../shared/services/feature-configuration.service';
import { HttpService } from '../../../shared/services/http.service';
import { MeetRoomClientResponseOptions } from '../models/room-request';
@Injectable({
providedIn: 'root'
@ -36,8 +37,12 @@ export class RoomService {
* @param options - The options for creating the room
* @returns A promise that resolves to the created MeetRoom object
*/
async createRoom(options?: MeetRoomOptions): Promise<MeetRoom> {
return this.httpService.postRequest(this.ROOMS_API, options);
async createRoom(options?: MeetRoomOptions, responseOptions?: MeetRoomClientResponseOptions): Promise<MeetRoom> {
const headers: Record<string, string> = {
'X-Fields': responseOptions?.fields ? responseOptions.fields.join(',') : '',
'X-Expand': responseOptions?.expand ? responseOptions.expand.join(',') : ''
};
return this.httpService.postRequest(this.ROOMS_API, options, headers);
}
/**
@ -80,8 +85,17 @@ export class RoomService {
* @param roomId - The unique identifier of the room
* @return A promise that resolves to the MeetRoom object
*/
async getRoom(roomId: string): Promise<MeetRoom> {
const path = `${this.ROOMS_API}/${roomId}`;
async getRoom(roomId: string, responseOptions?: MeetRoomClientResponseOptions): Promise<MeetRoom> {
const queryParams = new URLSearchParams();
if (responseOptions?.fields) {
queryParams.set('fields', responseOptions.fields.join(','));
}
if (responseOptions?.expand) {
queryParams.set('expand', responseOptions.expand.join(','));
}
const queryString = queryParams.toString();
const path = `${this.ROOMS_API}/${roomId}${queryString ? `?${queryString}` : ''}`;
return this.httpService.getRequest(path);
}

View File

@ -77,27 +77,6 @@ export interface MeetRoomFilters extends SortAndPagination {
expand?: MeetRoomExpandableProperties[];
}
/**
* Options for configuring the response MeetRoom REST API object
*/
export interface MeetRoomResponseOptions {
/**
* Array of fields to include in the response.
* If not specified, all fields are included.
*/
fields?: MeetRoomField[];
/**
* Array of collapsed properties to expand in the response.
* If not specified, no collapsed properties are expanded.
*/
collapse?: MeetRoomCollapsibleProperties[];
/**
* Whether to check permissions for the room.
* If true, sensitive properties will be removed from the response if the requester does not have permission to view them.
*/
applyPermissionFiltering?: boolean;
}
/**
* Stub that indicates a property can be expanded.
*/