private init()

in src/router/routes/genericResourceRoute.ts [30:296]


    private init() {
        // TODO handle HTTP response code
        if (this.operations.includes('read')) {
            // READ
            this.router.get(
                '/:id',
                RouteHelper.wrapAsync(async (req: express.Request, res: express.Response) => {
                    // Get the ResourceType looks like '/Patient'
                    const { id, resourceType } = req.params;
                    const response = await this.handler.read(resourceType, id, res.locals.tenantId);
                    const updatedReadResponse = await this.authService.authorizeAndFilterReadResponse({
                        operation: 'read',
                        userIdentity: res.locals.userIdentity,
                        requestContext: res.locals.requestContext,
                        readResponse: response,
                        fhirServiceBaseUrl: res.locals.serverUrl,
                    });
                    if (updatedReadResponse && updatedReadResponse.meta) {
                        res.set({
                            ETag: `W/"${updatedReadResponse.meta.versionId}"`,
                            'Last-Modified': updatedReadResponse.meta.lastUpdated,
                        });
                    }
                    res.send(updatedReadResponse);
                }),
            );
        }

        // VREAD
        if (this.operations.includes('vread')) {
            this.router.get(
                '/:id/_history/:vid',
                RouteHelper.wrapAsync(async (req: express.Request, res: express.Response) => {
                    // Get the ResourceType looks like '/Patient'
                    const { id, vid, resourceType } = req.params;
                    const response = await this.handler.vRead(resourceType, id, vid, res.locals.tenantId);
                    const updatedReadResponse = await this.authService.authorizeAndFilterReadResponse({
                        operation: 'vread',
                        userIdentity: res.locals.userIdentity,
                        requestContext: res.locals.requestContext,
                        readResponse: response,
                        fhirServiceBaseUrl: res.locals.serverUrl,
                    });
                    if (updatedReadResponse && updatedReadResponse.meta) {
                        res.set({
                            ETag: `W/"${updatedReadResponse.meta.versionId}"`,
                            'Last-Modified': updatedReadResponse.meta.lastUpdated,
                        });
                    }
                    res.send(updatedReadResponse);
                }),
            );
        }

        // Type History
        if (this.operations.includes('history-type')) {
            this.router.get(
                '/_history',
                RouteHelper.wrapAsync(async (req: express.Request, res: express.Response) => {
                    // Get the ResourceType looks like '/Patient'
                    const { resourceType } = req.params;
                    const searchParamQuery = req.query;
                    const response = await this.handler.typeHistory(
                        resourceType,
                        searchParamQuery,
                        res.locals.userIdentity,
                        res.locals.requestContext,
                        res.locals.tenantId,
                    );
                    const updatedReadResponse = await this.authService.authorizeAndFilterReadResponse({
                        operation: 'history-type',
                        userIdentity: res.locals.userIdentity,
                        requestContext: res.locals.requestContext,
                        readResponse: response,
                        fhirServiceBaseUrl: res.locals.serverUrl,
                    });
                    res.send(updatedReadResponse);
                }),
            );
        }

        // Instance History
        if (this.operations.includes('history-instance')) {
            this.router.get(
                '/:id/_history',
                RouteHelper.wrapAsync(async (req: express.Request, res: express.Response) => {
                    // Get the ResourceType looks like '/Patient'
                    const searchParamQuery = req.query;
                    const { id, resourceType } = req.params;
                    const response = await this.handler.instanceHistory(
                        resourceType,
                        id,
                        searchParamQuery,
                        res.locals.userIdentity,
                        res.locals.requestContext,
                        res.locals.tenantId,
                    );
                    const updatedReadResponse = await this.authService.authorizeAndFilterReadResponse({
                        operation: 'history-instance',
                        userIdentity: res.locals.userIdentity,
                        requestContext: res.locals.requestContext,
                        readResponse: response,
                        fhirServiceBaseUrl: res.locals.serverUrl,
                    });
                    res.send(updatedReadResponse);
                }),
            );
        }

        if (this.operations.includes('search-type')) {
            const handleSearch = async (res: express.Response, resourceType: string, searchParamQuery: any) => {
                return this.handler.typeSearch(
                    resourceType,
                    searchParamQuery,
                    res.locals.userIdentity,
                    res.locals.requestContext,
                    res.locals.serverUrl,
                    res.locals.tenantId,
                );
            };
            // SEARCH
            this.router.get(
                '/',
                RouteHelper.wrapAsync(async (req: express.Request, res: express.Response) => {
                    // Get the ResourceType looks like '/Patient'
                    const { resourceType } = req.params;
                    const searchParamQuery = req.query;
                    const updatedSearchResponse = await handleSearch(res, resourceType, searchParamQuery);
                    res.send(updatedSearchResponse);
                }),
            );
            this.router.post(
                '/_search',
                RouteHelper.wrapAsync(async (req: express.Request, res: express.Response) => {
                    // Get the ResourceType looks like '/Patient'
                    const { resourceType } = req.params;
                    const searchParamQuery = req.query;
                    const { body } = req;

                    if (!isEmpty(body)) {
                        mergeWith(searchParamQuery, body, (valueOne, valueTwo) => {
                            if (
                                !isEmpty(valueOne) &&
                                !isEmpty(valueTwo) &&
                                (Array.isArray(valueOne) || Array.isArray(valueTwo) || valueOne !== valueTwo)
                            ) {
                                return [...new Set([].concat(valueOne, valueTwo))];
                            }
                            return undefined; // Merging is handled by lodash mergeWith if undefined is returned
                        });
                    }

                    const updatedSearchResponse = await handleSearch(res, resourceType, searchParamQuery);
                    res.send(updatedSearchResponse);
                }),
            );
        }

        // CREATE
        if (this.operations.includes('create')) {
            this.router.post(
                '/',
                RouteHelper.wrapAsync(async (req: express.Request, res: express.Response) => {
                    // Get the ResourceType looks like '/Patient'
                    const { resourceType } = req.params;
                    const { body } = req;

                    await this.authService.isWriteRequestAuthorized({
                        resourceBody: body,
                        operation: 'create',
                        userIdentity: res.locals.userIdentity,
                        requestContext: res.locals.requestContext,
                        fhirServiceBaseUrl: res.locals.serverUrl,
                    });

                    const response = await this.handler.create(resourceType, body, res.locals.tenantId);
                    if (response && response.meta) {
                        res.set({ ETag: `W/"${response.meta.versionId}"`, 'Last-Modified': response.meta.lastUpdated });
                    }
                    res.status(201).send(response);
                }),
            );
        }

        // UPDATE
        if (this.operations.includes('update')) {
            this.router.put(
                '/:id',
                RouteHelper.wrapAsync(async (req: express.Request, res: express.Response) => {
                    const { id, resourceType } = req.params;
                    const { body } = req;

                    if (body.id === null || body.id !== id) {
                        throw new createError.BadRequest(
                            `Can not update resource with ID[${id}], while the given request payload has an ID[${body.id}]`,
                        );
                    }
                    await this.authService.isWriteRequestAuthorized({
                        resourceBody: body,
                        operation: 'update',
                        userIdentity: res.locals.userIdentity,
                        requestContext: res.locals.requestContext,
                        fhirServiceBaseUrl: res.locals.serverUrl,
                    });

                    const response = await this.handler.update(resourceType, id, body, res.locals.tenantId);
                    if (response && response.meta) {
                        res.set({ ETag: `W/"${response.meta.versionId}"`, 'Last-Modified': response.meta.lastUpdated });
                    }
                    res.send(response);
                }),
            );
        }

        // PATCH
        if (this.operations.includes('patch')) {
            this.router.patch(
                '/:id',
                RouteHelper.wrapAsync(async (req: express.Request, res: express.Response) => {
                    const { id, resourceType } = req.params;
                    const { body } = req;

                    if (body.id && body.id !== id) {
                        throw new createError.BadRequest(
                            `Can not update resource with ID[${id}], while the given request payload has an ID[${body.id}]`,
                        );
                    }
                    await this.authService.isWriteRequestAuthorized({
                        resourceBody: body,
                        operation: 'patch',
                        userIdentity: res.locals.userIdentity,
                        requestContext: res.locals.requestContext,
                        fhirServiceBaseUrl: res.locals.serverUrl,
                    });

                    const response = await this.handler.patch(resourceType, id, body, res.locals.tenantId);
                    if (response && response.meta) {
                        res.set({ ETag: `W/"${response.meta.versionId}"`, 'Last-Modified': response.meta.lastUpdated });
                    }
                    res.send(response);
                }),
            );
        }

        // DELETE
        if (this.operations.includes('delete')) {
            this.router.delete(
                '/:id',
                RouteHelper.wrapAsync(async (req: express.Request, res: express.Response) => {
                    // Get the ResourceType looks like '/Patient'
                    const { id, resourceType } = req.params;
                    const readResponse = await this.handler.read(resourceType, id, res.locals.tenantId);

                    await this.authService.isWriteRequestAuthorized({
                        resourceBody: readResponse,
                        operation: 'delete',
                        userIdentity: res.locals.userIdentity,
                        requestContext: res.locals.requestContext,
                        fhirServiceBaseUrl: res.locals.serverUrl,
                    });

                    const response = await this.handler.delete(resourceType, id, res.locals.tenantId);
                    res.send(response);
                }),
            );
        }
    }