Class: UniversalRenderer::Client::Base

Inherits:
Object
  • Object
show all
Defined in:
lib/universal_renderer/client/base.rb

Overview

Fetches server-side rendered (SSR) content from the Node.js service in a single, blocking request. This client is used when SSR content is needed in its entirety before the Rails view rendering proceeds, as opposed to streaming SSR.

Class Method Summary collapse

Class Method Details

.call(url, props) ⇒ UniversalRenderer::SSR::Response?

Performs a POST request to the SSR service to retrieve the complete SSR content. This is used for non-streaming SSR, where the entire payload is fetched before the main application view is rendered.

Parameters:

  • url (String)

    The URL of the page to render on the SSR server. This should typically be the request.original_url from the controller.

  • props (Hash)

    A hash of props to be passed to the SSR service. These props will be available to the frontend components for rendering.

Returns:



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/universal_renderer/client/base.rb', line 27

def self.call(url, props)
  ssr_url = UniversalRenderer.config.url
  return if ssr_url.blank?

  timeout = UniversalRenderer.config.timeout

  begin
    uri = URI.parse(ssr_url)
    request = Net::HTTP::Post.new(uri.request_uri)
    request.body = { url: url, props: props }.to_json
    request["Content-Type"] = "application/json"

    response = HttpPool.request(uri, timeout, request)

    if response.is_a?(Net::HTTPSuccess)
      raw_data = JSON.parse(response.body).deep_symbolize_keys

      # Map the keys we care about to the Struct. The Node service might
      # send `:body_html` instead of `:body`; favour the latter if
      # present but fall back gracefully.
      UniversalRenderer::SSR::Response.new(
        head: raw_data[:head],
        body: raw_data[:body] || raw_data[:body_html],
        body_attrs: raw_data[:body_attrs]
      )
    else
      UniversalRenderer.log do |log|
        log.error(
          "SSR fetch request to #{ssr_url} failed: #{response.code} - #{response.message} (URL: #{url})"
        )
      end
      nil
    end
  rescue Net::OpenTimeout, Net::ReadTimeout => e
    UniversalRenderer.log do |log|
      log.error(
        "SSR fetch request to #{ssr_url} timed out: #{e.class.name} - #{e.message} (URL: #{url})"
      )
    end
    nil
  rescue StandardError => e
    UniversalRenderer.log do |log|
      log.error(
        "SSR fetch request to #{ssr_url} failed: #{e.class.name} - #{e.message} (URL: #{url})"
      )
    end
    nil
  end
end