
June 10, 2025
As developers, we often find ourselves building APIs that need to be consumed by mobile apps, front-end frameworks, or third-party services.
A well-structured, documented, and maintainable API is essential for seamless integration and long-term scalability.
In this article, Iβll walk you through how to build a simple Ruby on Rails API that returns sunrise/sunset-like data β complete with Swagger (OpenAPI) documentation using the swagger-blocks gem.
This project gives you a solid foundation to build upon, whether you’re faking data or integrating with real-world APIs like sunrisesunset.io.
π Letβs Improve or Build Your API
If youβre looking to create a new API or enhance an existing one, using tools like Ruby on Rails, JBuilder, and Swagger documentation, I can help you build a clean, scalable, and well-documented service β just like we did with the Sun Data API.
Whether you’re integrating third-party data, optimizing performance, or ensuring developer-friendly documentation, I provide end-to-end support for API development in Ruby on Rails and beyond.
π§ Project Overview: Sun Data API

Weβre going to create a minimal API that returns simulated sunrise and sunset information based on location and date.
While weβll start with static/faked data, the structure will allow easy future integration with an external API.
Hereβs what weβll cover:
β Setting up a new Rails API-only application
β Using JBuilder for clean JSON responses
β Adding Swagger documentation via swagger-blocks
β Mounting Swagger UI for interactive exploration
β Planning for future integration with a real service
Letβs dive in!
1οΈβ£ Step 1: Setup Your Rails App
Start by creating a new Rails API app:
rails new sun_api --api
cd sun_api
Add these gems to your Gemfile:
gem 'jbuilder' # For JSON views
gem 'swagger-blocks' # For Swagger docs
gem 'swagger-ui_rails' # For interactive UI
Then install them:
bundle install
2οΈβ£ Step 2: Generate the Controller
Create a controller for handling our API requests:
rails g controller Api::V1::SunDataController
Now, update app/controllers/api/v1/sun_data_controller.rb:
module Api
module V1
class SunDataController < ApplicationController
include Swagger::Blocks
swagger_path '/sun_data' do
operation :get do
key :summary, 'Get sunrise/sunset info'
key :description, 'Returns sunrise, sunset, and related time data for a given date and location'
key :produces, ['application/json']
key :tags, ['Sun Data']
parameter :lat do
key :name, :lat
key :in, :query
key :description, 'Latitude of the location'
key :required, true
key :type, :number
end
parameter :lng do
key :name, :lng
key :in, :query
key :description, 'Longitude of the location'
key :required, true
key :type, :number
end
parameter :date do
key :name, :date
key :in, :query
key :description, 'Date in YYYY-MM-DD format'
key :required, false
key :type, :string
key :format, :date
end
response 200 do
key :description, 'Successful response'
schema do
key :'$ref', :SunDataResponse
end
end
end
end
def show
@data = {
results: {
date: params[:date] || Date.today.to_s,
sunrise: "7:06:58 AM",
sunset: "4:48:45 PM",
first_light: "5:32:42 AM",
last_light: "6:23:02 PM",
dawn: "6:37:39 AM",
dusk: "5:18:04 PM",
solar_noon: "11:57:52 AM",
golden_hour: "4:07:57 PM",
day_length: "9:41:47",
timezone: "America/New_York",
utc_offset: -300
},
status: "OK"
}
respond_to do |format|
format.json
end
end
end
end
end
3οΈβ£ Step 3: Create a JBuilder View
JBuilder makes it easy to generate clean, structured JSON responses.
Create the file: app/views/api/v1/sun_data/show.json.jbuilder
json.results do
json.date @data[:results][:date]
json.sunrise @data[:results][:sunrise]
json.sunset @data[:results][:sunset]
json.first_light @data[:results][:first_light]
json.last_light @data[:results][:last_light]
json.dawn @data[:results][:dawn]
json.dusk @data[:results][:dusk]
json.solar_noon @data[:results][:solar_noon]
json.golden_hour @data[:results][:golden_hour]
json.day_length @data[:results][:day_length]
json.timezone @data[:results][:timezone]
json.utc_offset @data[:results][:utc_offset]
end
json.status @data[:status]
4οΈβ£ Step 4: Add Swagger Schemas
Create an initializer for Swagger blocks: config/initializers/swagger_blocks.rb
require 'swagger/blocks'
Swagger::Blocks.configure do |c|
c.swagger_version = '2.0'
c.template_dir = Rails.root.join('app', 'swagger')
end
Then define your schema models in: app/swagger/sun_data_response.rb
class SunDataResponse
include Swagger::Blocks
swagger_schema :SunDataResponse do
key :required, [:results, :status]
property :results do
key :'$ref', :SunDataResult
end
property :status, type: :string
end
swagger_schema :SunDataResult do
key :required, [
:date, :sunrise, :sunset, :first_light, :last_light,
:dawn, :dusk, :solar_noon, :golden_hour, :day_length,
:timezone, :utc_offset
]
property :date, type: :string, format: :date
property :sunrise, type: :string
property :sunset, type: :string
property :first_light, type: :string
property :last_light, type: :string
property :dawn, type: :string
property :dusk, type: :string
property :solar_noon, type: :string
property :golden_hour, type: :string
property :day_length, type: :string
property :timezone, type: :string
property :utc_offset, type: :integer
end
end
5οΈβ£ Step 5: Mount Swagger UI
After installing the swagger-ui_rails gem, run:
rails generate swagger:ui
Update the config in: config/initializers/swagger_ui_rails.rb
SwaggerUiRails.configure do |c|
c.swagger_url = "/api-docs/sun_data.yaml"
end
π‘ Note: You’ll need to generate or manually create the /api-docs/sun_data.yaml file from your Swagger blocks later.
6οΈβ£ Step 6: Define Routes
Update your config/routes.rb:
Rails.application.routes.draw do
namespace :api do
namespace :v1 do
get 'sun_data', to: 'sun_data#show'
end
end
mount SwaggerUiRails::Engine => '/docs'
end
β Final Result
Start your server:
rails s
Now you can access:
π API Endpoint : http://localhost:3000/api/v1/sun_data?lat=38.9&lng=-77.03&date=2023-11-29
π Swagger Docs : http://localhost:3000/docs
π Next Steps
Once youβre ready to fetch real-time data, integrate tools like:
- π Faraday or HTTParty for calling external APIs
- ποΈ Active Record or another ORM if you want to persist or cache data
- π¦ Background jobs for asynchronous fetching
This setup ensures a clean separation between logic, presentation, and documentation β making it easy to scale and maintain.
π¬ Final Thoughts
Building APIs with proper documentation from the start saves immense time and effort down the line.
By combining JBuilder , Swagger , and Rails , you can create powerful, maintainable, and developer-friendly services that are a pleasure to work with β both for yourself and others consuming your API.

Have you used Swagger or other API documentation tools in your Rails projects? Share your experiences below π
π¨π» Want the full code?
You can find the example GitHub repo or template here (add link if available), or feel free to ask me for a downloadable ZIP or boilerplate setup.
π Follow Me for More Rails Tips & API Guides!
#RubyOnRails #APIDevelopment #Swagger #OpenAPI #Documentation #WebDevelopment #BackendDevelopment #RubyDeveloper #RailsAPI #SoftwareEngineering
Would you like me to generate a Markdown version of this for publishing directly on LinkedIn or as a blog post?