Ricardo Daniel
Ricardo Daniel

Reputation: 441

Angular 2 Universal + Akamai

I want to see if I can create a stack based on both, CDN and also angular 2 universal. So when the user navigate has the CDN to get the assets, and if the user access the first time will have the complete html rendered by Universal.

I was thinking in:

Client <===> Akamai <===> Varnish <===> Origin Server (node.js with universal)

This sounds good? have you ever tried it? Also i'm considering adding nginx and ELB for the complete stack.

The question is: - Can this stack work as expected?

Upvotes: 0

Views: 731

Answers (1)

Patrick Michalina
Patrick Michalina

Reputation: 1379

Yes it can be done! The big issue is how do you invalidate an arbitrary number of http requests made in Angular that determine the rendered page. Using some sort of header schema to invalidate might be helpful.

Assuming your are using official ng-express engine, a service like this could let you define the response from the Angular runtime:

import { RESPONSE } from '@nguniversal/express-engine/tokens'
import { Inject, Injectable, Optional } from '@angular/core'
import { Response } from 'express'

export interface IServerResponseService {
  getHeader(key: string): string
  setHeader(key: string, value: string): this
  setHeaders(dictionary: { [key: string]: string }): this
  appendHeader(key: string, value: string, delimiter?: string): this
  setStatus(code: number, message?: string): this
  setNotFound(message?: string): this
  setError(message?: string): this
}

@Injectable()
export class ServerResponseService implements IServerResponseService {

  private response: Response

  constructor(@Optional() @Inject(RESPONSE) res: any) {
    this.response = res
  }

  getHeader(key: string): string {
    return this.response.getHeader(key)
  }

  setHeader(key: string, value: string): this {
    if (this.response)
      this.response.header(key, value)
    return this
  }

  appendHeader(key: string, value: string, delimiter = ','): this {
    if (this.response) {
      const current = this.getHeader(key)
      if (!current) return this.setHeader(key, value)

      const newValue = [...current.split(delimiter), value]
        .filter((el, i, a) => i === a.indexOf(el))
        .join(delimiter)

      this.response.header(key, newValue)
    }
    return this
  }

  setHeaders(dictionary: { [key: string]: string }): this {
    if (this.response)
      Object.keys(dictionary).forEach(key => this.setHeader(key, dictionary[key]))
    return this
  }

  setStatus(code: number, message?: string): this {
    if (this.response) {
      this.response.statusCode = code
      if (message)
        this.response.statusMessage = message
    }
    return this
  }

  setNotFound(message = 'not found'): this {
    if (this.response) {
      this.response.statusCode = 404
      this.response.statusMessage = message
    }
    return this
  }

  setError(message = 'internal server error'): this {
    if (this.response) {
      this.response.statusCode = 500
      this.response.statusMessage = message
    }
    return this
  }
}

Upvotes: 0

Related Questions