From eacd629006d2c0825fcc193e232969b9a3a24e21 Mon Sep 17 00:00:00 2001 From: CSantosM <4a.santos@gmail.com> Date: Fri, 6 Feb 2026 18:32:06 +0100 Subject: [PATCH] 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. --- meet-ce/backend/src/models/room-response.ts | 23 +++++++++++++++++++ meet-ce/backend/src/services/room.service.ts | 8 +++---- .../meeting/services/meeting-lobby.service.ts | 5 +++- .../rooms/guards/room-edit-check.guard.ts | 4 +++- .../lib/domains/rooms/models/room-request.ts | 17 ++++++++++++++ .../room-wizard/room-wizard.component.ts | 9 +++++--- .../rooms/pages/rooms/rooms.component.ts | 3 ++- .../domains/rooms/services/room.service.ts | 22 ++++++++++++++---- meet-ce/typings/src/room-response.ts | 21 ----------------- 9 files changed, 77 insertions(+), 35 deletions(-) create mode 100644 meet-ce/backend/src/models/room-response.ts create mode 100644 meet-ce/frontend/projects/shared-meet-components/src/lib/domains/rooms/models/room-request.ts diff --git a/meet-ce/backend/src/models/room-response.ts b/meet-ce/backend/src/models/room-response.ts new file mode 100644 index 00000000..8ef25d15 --- /dev/null +++ b/meet-ce/backend/src/models/room-response.ts @@ -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; +} diff --git a/meet-ce/backend/src/services/room.service.ts b/meet-ce/backend/src/services/room.service.ts index c3824e37..0e11130e 100644 --- a/meet-ce/backend/src/services/room.service.ts +++ b/meet-ce/backend/src/services/room.service.ts @@ -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} A promise that resolves to the created OpenVidu room. * * @throws {Error} If the room creation fails. * */ - async createMeetRoom(roomOptions: MeetRoomOptions, responseOpts?: MeetRoomResponseOptions): Promise { + async createMeetRoom(roomOptions: MeetRoomOptions, responseOpts?: MeetRoomServerResponseOptions): Promise { 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 { + async getMeetRoom(roomId: string, responseOpts?: MeetRoomServerResponseOptions): Promise { const { collapse, applyPermissionFiltering, fields } = responseOpts || {}; let room = await this.roomRepository.findByRoomId(roomId, fields); diff --git a/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/meeting/services/meeting-lobby.service.ts b/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/meeting/services/meeting-lobby.service.ts index d4cb7390..ef063081 100644 --- a/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/meeting/services/meeting-lobby.service.ts +++ b/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/meeting/services/meeting-lobby.service.ts @@ -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() diff --git a/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/rooms/guards/room-edit-check.guard.ts b/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/rooms/guards/room-edit-check.guard.ts index 8501f1eb..cf727e56 100644 --- a/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/rooms/guards/room-edit-check.guard.ts +++ b/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/rooms/guards/room-edit-check.guard.ts @@ -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`); diff --git a/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/rooms/models/room-request.ts b/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/rooms/models/room-request.ts new file mode 100644 index 00000000..215e58ce --- /dev/null +++ b/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/rooms/models/room-request.ts @@ -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[]; +} diff --git a/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/rooms/pages/room-wizard/room-wizard.component.ts b/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/rooms/pages/room-wizard/room-wizard.component.ts index 25b573bd..69d44ca7 100644 --- a/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/rooms/pages/room-wizard/room-wizard.component.ts +++ b/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/rooms/pages/room-wizard/room-wizard.component.ts @@ -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); diff --git a/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/rooms/pages/rooms/rooms.component.ts b/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/rooms/pages/rooms/rooms.component.ts index abd24a61..32f6cb50 100644 --- a/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/rooms/pages/rooms/rooms.component.ts +++ b/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/rooms/pages/rooms/rooms.component.ts @@ -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 diff --git a/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/rooms/services/room.service.ts b/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/rooms/services/room.service.ts index 0625d944..8b44d8d3 100644 --- a/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/rooms/services/room.service.ts +++ b/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/rooms/services/room.service.ts @@ -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 { - return this.httpService.postRequest(this.ROOMS_API, options); + async createRoom(options?: MeetRoomOptions, responseOptions?: MeetRoomClientResponseOptions): Promise { + const headers: Record = { + '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 { - const path = `${this.ROOMS_API}/${roomId}`; + async getRoom(roomId: string, responseOptions?: MeetRoomClientResponseOptions): Promise { + 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); } diff --git a/meet-ce/typings/src/room-response.ts b/meet-ce/typings/src/room-response.ts index 092de4e4..02c665ab 100644 --- a/meet-ce/typings/src/room-response.ts +++ b/meet-ce/typings/src/room-response.ts @@ -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. */