Building the Core: Webhook and Request Models
2 min read
💡 See the code for this post on the 🔗 core-models branch.
After creating our database structure in the previous chapter, it’s time to add logic to our models. The models are the core of our application, handling data validation and relationships.
The Webhook Model
Let’s start with the Webhook model. This model needs to:
- Generate a unique UUID for new webhooks
- Check if a webhook has expired
- Manage its relationship with webhook requests
Here’s how I implemented these requirements:
class Webhook < ApplicationRecord
has_many :webhook_requests, dependent: :destroy
validates :uuid, presence: true, uniqueness: true
validates :expired_at, presence: true
before_validation :set_uuid, on: :create
def expired?
Time.current.to_date > expired_at
end
private
def set_uuid
self.uuid = SecureRandom.uuid if uuid.blank?
end
end
A few interesting things about this model:
- The
has_manyrelationship tells Rails that one webhook can have multiple webhook requests dependent: :destroyensures all related webhook requests are deleted when we delete a webhook- We use a
before_validationcallback to automatically set the UUID when creating a new webhook - The
expired?method helps us check if a webhook can still receive requests
The WebhookRequest Model
Next, I built the WebhookRequest model to store incoming HTTP requests. This model needs to:
- Store all the details of an incoming request
- Belong to a webhook
Here’s the implementation:
class WebhookRequest < ApplicationRecord
belongs_to :webhook
# Convert headers and query params to JSON before saving
before_save :ensure_json_format
private
def ensure_json_format
self.headers = headers.to_json unless headers.is_a?(String)
self.query_params = query_params.to_json unless query_params.is_a?(String)
end
end
The interesting parts of this model:
belongs_to :webhooksets up the relationship with the parent webhook- We validate all fields because each piece of request information is important
- The
ensure_json_formatcallback makes sure our headers and query parameters are stored as JSON strings
Testing the Models
Let’s test our models in the Rails console:
# Create a new webhook that expires in 7 days
webhook = Webhook.create!(expired_at: 7.days.from_now)
# Create a webhook request
request = webhook.webhook_requests.create!(
ip: "127.0.0.1",
url: "https://webhookdump.link/abc123",
method: "POST",
host: "webhookdump.link",
headers: {"Content-Type" => "application/json"},
query_params: {"key" => "value"},
payload: '{"message": "Hello World"}'
)
# Check if it worked
puts "Webhook UUID: #{webhook.uuid}"
puts "Request count: #{webhook.webhook_requests.count}"
puts "Is expired? #{webhook.expired?}"
With these models in place, our application can now:
- Create webhooks with unique identifiers
- Store incoming webhook requests with all their details
- Check if webhooks are still valid
- Maintain proper relationships between webhooks and their requests
In the next chapter, we’ll build the controllers to handle incoming webhook requests and display them to users.
Stay tuned! 🚀