Skip to content

Commit 576ff60

Browse files
committedSep 6, 2024
feat(@angular/ssr): introduce AngularNodeAppEngine API for Node.js integration
Expose a variant of `AngularAppEngine` tailored for Node.js. These additions streamline the process by minimizing boilerplate code and eliminate the need for users to call `createWebRequestFromNodeRequest` before invoking the render method.
1 parent ecc107d commit 576ff60

File tree

3 files changed

+113
-0
lines changed

3 files changed

+113
-0
lines changed
 

‎goldens/public-api/angular/ssr/node/index.api.md

+12
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,16 @@
66

77
import { ApplicationRef } from '@angular/core';
88
import type { IncomingMessage } from 'node:http';
9+
import type { IncomingMessage as IncomingMessage_2 } from 'http';
910
import type { ServerResponse } from 'node:http';
1011
import { StaticProvider } from '@angular/core';
1112
import { Type } from '@angular/core';
1213

14+
// @public
15+
export interface AngularNodeServerAppManager {
16+
render(request: Request | IncomingMessage_2, requestContext?: unknown): Promise<Response | null>;
17+
}
18+
1319
// @public
1420
export class CommonEngine {
1521
constructor(options?: CommonEngineOptions | undefined);
@@ -40,6 +46,12 @@ export interface CommonEngineRenderOptions {
4046
// @public
4147
export function createWebRequestFromNodeRequest(nodeRequest: IncomingMessage): Request;
4248

49+
// @public
50+
export function destroyAngularNodeAppEngine(): void;
51+
52+
// @public
53+
export function getOrCreateAngularNodeAppEngine(): AngularNodeServerAppManager;
54+
4355
// @public
4456
export function writeResponseToNodeResponse(source: Response, destination: ServerResponse): Promise<void>;
4557

‎packages/angular/ssr/node/public_api.ts

+6
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,11 @@ export {
1212
type CommonEngineOptions,
1313
} from './src/common-engine/common-engine';
1414

15+
export {
16+
type AngularNodeServerAppManager,
17+
destroyAngularNodeAppEngine,
18+
getOrCreateAngularNodeAppEngine,
19+
} from './src/app-engine';
20+
1521
export { writeResponseToNodeResponse } from './src/response';
1622
export { createWebRequestFromNodeRequest } from './src/request';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.dev/license
7+
*/
8+
9+
import { ɵAngularAppEngine as AngularAppEngine } from '@angular/ssr';
10+
import type { IncomingMessage } from 'http';
11+
import { createWebRequestFromNodeRequest } from './request';
12+
13+
/**
14+
* Angular server application engine.
15+
* Manages Angular server applications (including localized ones) and handles rendering requests.
16+
17+
* @developerPreview
18+
*/
19+
export interface AngularNodeServerAppManager {
20+
/**
21+
* Renders an HTTP response based on the incoming request using the Angular server application.
22+
*
23+
* The method processes the incoming request, determines the appropriate route, and prepares the
24+
* rendering context to generate a response. If the request URL corresponds to a static file (excluding `/index.html`),
25+
* the method returns `null`.
26+
*
27+
* Example: A request to `https://www.example.com/page/index.html` will render the Angular route
28+
* associated with `https://www.example.com/page`.
29+
*
30+
* @param request - The incoming HTTP request object to be rendered. It can be a `Request` or `IncomingMessage` object.
31+
* @param requestContext - Optional additional context for the request, such as metadata or custom settings.
32+
* @returns A promise that resolves to a `Response` object, or `null` if the request URL is for a static file
33+
* (e.g., `./logo.png`) rather than an application route.
34+
*/
35+
render(request: Request | IncomingMessage, requestContext?: unknown): Promise<Response | null>;
36+
}
37+
38+
/**
39+
* Angular server application engine.
40+
* Manages Angular server applications (including localized ones), handles rendering requests,
41+
* and optionally transforms index HTML before rendering.
42+
*/
43+
export class AngularNodeAppEngine extends AngularAppEngine implements AngularNodeServerAppManager {
44+
/**
45+
* Renders an HTTP response based on the incoming request using the Angular server application.
46+
*
47+
* The method processes the incoming request, determines the appropriate route, and prepares the
48+
* rendering context to generate a response. If the request URL corresponds to a static file (excluding `/index.html`),
49+
* the method returns `null`.
50+
*
51+
* Example: A request to `https://www.example.com/page/index.html` will render the Angular route
52+
* associated with `https://www.example.com/page`.
53+
*
54+
* @param request - The incoming HTTP request object to be rendered. It can be a `Request` or `IncomingMessage` object.
55+
* @param requestContext - Optional additional context for the request, such as metadata or custom settings.
56+
* @returns A promise that resolves to a `Response` object, or `null` if the request URL is for a static file
57+
* (e.g., `./logo.png`) rather than an application route.
58+
*/
59+
override render(
60+
request: Request | IncomingMessage,
61+
requestContext?: unknown,
62+
): Promise<Response | null> {
63+
const webReq = request instanceof Request ? request : createWebRequestFromNodeRequest(request);
64+
65+
return super.render(webReq, requestContext);
66+
}
67+
}
68+
69+
let angularNodeAppEngine: AngularNodeAppEngine | undefined;
70+
71+
/**
72+
* Retrieves the existing `AngularNodeAppEngine` instance or creates a new one if it doesn't exist.
73+
*
74+
* This method ensures that a single instance of `AngularNodeAppEngine` is used throughout the application's lifecycle,
75+
* promoting efficient resource management. If an instance does not exist, it will be instantiated upon the first call.
76+
*
77+
* @developerPreview
78+
* @returns The existing or newly created instance of `AngularNodeAppEngine`.
79+
*/
80+
export function getOrCreateAngularNodeAppEngine(): AngularNodeServerAppManager {
81+
return (angularNodeAppEngine ??= new AngularNodeAppEngine());
82+
}
83+
84+
/**
85+
* Destroys the current `AngularNodeAppEngine` instance and releases any associated resources.
86+
*
87+
* This method resets the reference to the `AngularNodeAppEngine` instance to `undefined`, allowing for the creation
88+
* of a new instance on subsequent calls to `getOrCreateAngularNodeAppEngine()`. This is typically used when
89+
* reinitializing the server environment or refreshing the application state.
90+
*
91+
* @developerPreview
92+
*/
93+
export function destroyAngularNodeAppEngine(): void {
94+
angularNodeAppEngine = undefined;
95+
}

0 commit comments

Comments
 (0)
Please sign in to comment.