New bootstrap.json endpoint for starting up Discourse

Discourse needs a bunch of data preloaded before it can start up.
Normally we throw blobs of this into the HTML document that is requested
but in some cases that's awkward to retrieve.

For example with Ember CLI you have a separate javascript application
that needs to make its own HTML.

This API endpoint returns a JSON object with all the data Discourse needs to
bootstrap and start up.
This commit is contained in:
Robin Ward 2020-06-03 14:45:23 -04:00
parent ba00cc8ec4
commit 22789e0201
4 changed files with 72 additions and 0 deletions

View File

@ -0,0 +1,29 @@
# frozen_string_literal: true
class BootstrapController < ApplicationController
include ApplicationHelper
include ActionView::Helpers::AssetUrlHelper
# This endpoint allows us to produce the data required to start up Discourse via JSON API,
# so that you don't have to scrape the HTML for `data-*` payloads
def index
locale = script_asset_path("locales/#{I18n.locale}")
preload_anonymous_data
if current_user
current_user.sync_notification_channel_position
preload_current_user_data
end
bootstrap = {
theme_ids: theme_ids,
title: SiteSetting.title,
current_homepage: current_homepage,
locale_script: "#{Discourse.base_url}#{locale}",
setup_data: client_side_setup_data,
preloaded: @preloaded
}
render_json_dump(bootstrap: bootstrap)
end
end

View File

@ -356,6 +356,7 @@ module ApplicationHelper
end
def loading_admin?
return false unless defined?(controller)
controller.class.name.split("::").first == "Admin"
end

View File

@ -14,6 +14,8 @@ Discourse::Application.routes.draw do
match "/404", to: "exceptions#not_found", via: [:get, :post]
get "/404-body" => "exceptions#not_found_body"
get "/bootstrap" => "bootstrap#index"
post "webhooks/aws" => "webhooks#aws"
post "webhooks/mailgun" => "webhooks#mailgun"
post "webhooks/mailjet" => "webhooks#mailjet"

View File

@ -0,0 +1,40 @@
# frozen_string_literal: true
require 'rails_helper'
describe BootstrapController do
it "returns data as anonymous" do
get "/bootstrap.json"
expect(response.status).to eq(200)
json = response.parsed_body
expect(json).to be_present
bootstrap = json['bootstrap']
expect(bootstrap).to be_present
expect(bootstrap['title']).to be_present
expect(bootstrap['setup_data']['base_url']).to eq(Discourse.base_url)
preloaded = bootstrap['preloaded']
expect(preloaded['site']).to be_present
expect(preloaded['siteSettings']).to be_present
expect(preloaded['currentUser']).to be_blank
expect(preloaded['topicTrackingStates']).to be_blank
end
it "returns user data when authenticated" do
user = Fabricate(:user)
sign_in(user)
get "/bootstrap.json"
expect(response.status).to eq(200)
json = response.parsed_body
expect(json).to be_present
bootstrap = json['bootstrap']
preloaded = bootstrap['preloaded']
expect(preloaded['currentUser']).to be_present
expect(preloaded['topicTrackingStates']).to be_present
end
end