Ruby on Rails

Obrazki OG w
Ruby on Rails

Hook after_commit, Active Job, adres zapisany w rekordzie.

Gdzie to wpiąć

Rails nie ma odpowiednika bibliotek do obrazków na edge, z których korzysta świat JavaScriptu, więc zwykle kończy się na Chrome uruchomionym obok aplikacji przez Grover albo Ferrum — i na pilnowaniu go. Job z jednym żądaniem HTTP trzyma Chrome z dala od Twoich serwerów i sam ponawia próbę, gdy sieć się zająknie.

app/jobs/generate_og_image_job.rb

require "net/http"

class GenerateOgImageJob < ApplicationJob
  queue_as :default
  retry_on Net::OpenTimeout, Net::ReadTimeout, wait: :polynomially_longer, attempts: 3

  ENDPOINT = URI("https://imageapi.dev/v1/images?wait=true")

  def perform(post)
    body = {
      template: "blog-og",
      modifications: {
        title: post.title,
        author: post.author.name,
        date: post.published_at.to_date.iso8601,
        site: "yourblog.com"
      }
    }

    response = Net::HTTP.start(ENDPOINT.host, ENDPOINT.port, use_ssl: true, read_timeout: 20) do |http|
      request = Net::HTTP::Post.new(ENDPOINT)
      request["Authorization"] = "Bearer #{Rails.application.credentials.image_api_key}"
      request["Content-Type"] = "application/json"
      request.body = body.to_json
      http.request(request)
    end

    response.value # raises on anything that is not 2xx
    post.update!(og_image_url: JSON.parse(response.body).fetch("url"))
  end
end

# app/models/post.rb
# after_commit -> { GenerateOgImageJob.perform_later(self) },
#   on: [:create, :update], if: -> { saved_change_to_title? && published? }
Pułapka

Używaj `after_commit`, nie `after_save`. Przy `after_save` job może wystartować przed zatwierdzeniem transakcji i worker wczyta wpis, którego nowego tytułu nie ma jeszcze w bazie — obrazek pokaże stary tytuł.

Co dostajesz w odpowiedzi

Z ?wait=true czekasz na gotowy obrazek w tym samym połączeniu — zwykle około sekundy.

{
    "id": "img_01m08s3ez1zcv28h335g9923bw",
    "status": "completed",
    "url": "https://cdn.imageapi.dev/renders/img_01m08s3ez1zcv28h335g9923bw.png",
    "duration_ms": 912
}

Ile to kosztuje

Sto obrazków miesięcznie za darmo, potem $9 za dwa tysiące. Ten sam wpis wyrenderowany drugi raz zwraca istniejący adres i nie zużywa limitu — więc przebudowanie strony nic nie kosztuje.

Inne frameworki