Как мне развернуть приложение React и Rails API в Heroku?
Я работаю над приложением, которое использует React в качестве клиента с Rails API в качестве сервера. Я хочу, чтобы клиент и сервер были как можно более раздельными (сейчас они находятся в совершенно разных репозиториях).
Клиент React был создан с помощью create-реагировать-приложение, и в настоящее время вызывает API, используя параметр прокси в файле package.json, например так:
"proxy": "http://localhost:3001/"
Localhost 3001 - это местоположение моего Rails API. Очевидно, что это не будет работать в производстве.
Как я могу развернуть это в Heroku, предоставляя клиенту доступ к серверу? Могу ли я развернуть два разных приложения Heroku и каким-то образом передать запросы прокси-приложений клиентского приложения в приложение сервера? Или мне нужно включить клиента в мой проект rails и развернуть его все вместе?
2 ответа
Я использовал другой подход, чем Джимми, делая то же самое.
Я развернул два приложения на Heroku: Rails API и интерфейс Create-React-App. Не вдаваясь в подробности, есть несколько ключей для настройки этого. Во-первых, в ваших рельсах API, отредактируйте cors.rb
файл, так что он позволяет запросы из разных источников:
Rails.application.config.middleware.insert_before 0, Rack::Cors do
allow do
origins 'localhost:3000', 'https://myapp.herokuapp.com'
resource '*',
headers: :any,
methods: [:get, :post, :put, :delete],
end
end
Как следует из этого файла, мое приложение rails не работает на localhost:3000
локально, я изменил его для запуска на порт 8000 вместо редактирования puma.rb
:
port ENV.fetch("PORT") { 8000 }
Создайте-реакция-приложение работает на localhost:3000
локально по умолчанию, так что вы можете настроить rails api для работы на любом порте, который вы хотите, если он отличается от вашего интерфейса.
Затем я создал в своем приложении create-реагировать-приложение файл, содержащий URL-адрес API и часто используемые конечные точки, которые я вызываю. AppConstants.js
:
// let APIRoot = "http://localhost:8000";
let APIRoot = "https://my-rails-api.herokuapp.com";
export default {
APIEndpoints: {
LOGIN: APIRoot + "/users/login",
SIGNUP: APIRoot + "/users/create",
TODOS: APIRoot + "/todos",
ITEMS: APIRoot + "/items",
},
};
Теперь вы редактируете свои вызовы fetch / ajax / xmlHttpRequest так, чтобы используемый им URL ссылался на эти маршруты. Например, используя fetch:
fetch(AppConstants.TODOS, {
method: 'POST',
body: JSON.stringify(values)
})
.then(response => response.text())
.then((body) => {
console.log(body);
});
Этот файл констант приложения позволяет легко переключаться между локальным корнем API и рабочим корнем API.
Разверните ваши rails api на heroku, как обычно, автоматически найдется подходящий сборочный пакет. Для вашего приложения реагирования я предлагаю использовать этот сборочный пакет, поскольку он создаст производственную сборку вашего приложения create-реагировать и предоставит вам статические ресурсы.
Я делал это раньше. Я начал, как вы предложили в своем вопросе, с создания приложения реакции и включения его в мой проект rails и развертывания всего этого. Это работает просто отлично, но я не чувствовал необходимости заново развертывать свой серверный API каждый раз, когда я хотел развернуть свое интерфейсное приложение.
Итак, я сделал модель под названием FrontEndAppVersion
в моем приложении рельсы. Я дал этой модели две колонки:
- версия - строка семантической версии, которую вы обычно видите
- active - логическое значение, указывающее, была ли это активная версия (одновременно может быть активной только одна запись)
Я тогда имел минимальный рельс представления рендера, который будет искать активный FrontEndAppVersion
и будет ссылаться на соответствующие файлы js и css.
В своем приложении реакции я использовал gulp, чтобы упаковать приложение и перенести его в облачный фронт, с которым связано мое приложение rails. В дополнение к отправке реагирующих файлов в облачный фронт, я сделал так, чтобы он отправлял запрос API в мое бэкэнд-приложение rails, чтобы сообщить о наличии новой версии и сделать ее активной.
Это может быть излишним, но это также позволило мне с легкостью откатить версию. Вместо отката Heroku, я мог бы откатить только приложение на стороне клиента, сделав другой FrontEndAppVersion
запишите активный.
В любом случае прокси-сервер нужно будет изменить при его создании, и если оба приложения находятся в одном домене, вы можете просто использовать /
,