### Start Application with Rackup Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/configuration.md Command to start the application using rackup, which loads the config.ru file. This is another deployment option. ```bash bundle exec rackup config.ru ``` -------------------------------- ### Start Application with Passenger Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/configuration.md Command to start the application using Passenger, a production-ready application server. This is recommended for production environments. ```bash passenger start ``` -------------------------------- ### Root Index Request Examples Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/endpoints.md Examples of GET requests to the root index endpoint. One shows a standard request for the HTML page, and the other demonstrates requesting a random verse. ```http GET / GET /?random=true&translation=web ``` -------------------------------- ### Verse Example from /John+3:16 Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/types.md Example JSON response for a verse from the /:ref endpoint. ```json { "book_id": "JHN", "book_name": "John", "chapter": 3, "verse": 16, "text": "\nFor God so loved the world, that he gave his one and only Son, that whoever believes in him should not perish, but have eternal life.\n\n" } ``` -------------------------------- ### Book Example Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/types.md Example JSON response for a book in the /data/:translation response. ```json { "id": "GEN", "name": "Genesis", "url": "https://bible-api.com/data/web/GEN" } ``` -------------------------------- ### Start Puma Server Directly Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/configuration.md Command to start the Puma web server using a specific configuration file. This is one method for deploying the application. ```bash bundle exec puma -C config/puma.rb ``` -------------------------------- ### OPTIONS Preflight Request Example Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/endpoints.md Example of an OPTIONS preflight request to the CORS handler for a specific Bible reference. ```http OPTIONS /John+3:16 ``` -------------------------------- ### Rack::Attack Permissive Throttling Example Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/configuration.md Example configuration for permissive testing throttling, allowing 1000 requests per minute. ```env RACK_ATTACK_LIMIT=1000 RACK_ATTACK_PERIOD=60 # 1000 requests/minute ``` -------------------------------- ### Install Ruby Dependencies Source: https://github.com/seven1m/bible_api/blob/master/README.md Install the necessary Ruby gems for the bible_api application using Bundler. It's recommended to use 'bundle config --local deployment true' on a server. ```sh gem install bundler bundle config --local deployment true # optional, but prefered on a server bundle install ``` -------------------------------- ### Rack::AbuseMiddleware Initialization Example Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/api-reference/abuse_middleware.md Demonstrates how to use the Rack::AbuseMiddleware in a Rack application, specifying Redis connection and configuration parameters. ```ruby use Rack::AbuseMiddleware, redis: Redis.new, limit: 10, window: 30, block_time: 3600 ``` -------------------------------- ### Verse Reference Endpoint Request Example Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/endpoints.md Example of a GET request to the verse reference endpoint, demonstrating the use of path and query parameters for specifying a Bible reference and translation. ```http GET /John+3:16?translation=web&verse_numbers=false ``` -------------------------------- ### Example API Requests Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/README.md Demonstrates how to make various requests to the Bible API using curl, including fetching single verses, verses with specified translations, and verse ranges. Also shows examples for accessing data endpoints. ```bash # Single verse curl https://bible-api.com/John+3:16 # With translation curl https://bible-api.com/John+3:16?translation=kjv # Verse range curl https://bible-api.com/John+3:16-17 # Data API curl https://bible-api.com/data curl https://bible-api.com/data/web/random curl https://bible-api.com/data/web/JHN/3 ``` -------------------------------- ### Rack::Attack Strict Throttling Example Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/configuration.md Example configuration for strict API throttling, allowing 30 requests per minute. ```env RACK_ATTACK_LIMIT=30 RACK_ATTACK_PERIOD=60 # 30 requests/minute ``` -------------------------------- ### Verse Example from /data/web/JHN/3 Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/types.md Example JSON response for a verse from a data endpoint. ```json { "book_id": "JHN", "book": "John", "chapter": 3, "verse": 1, "text": "Now there was a Pharisee named Nicodemus, a ruler of the Jews." } ``` -------------------------------- ### Rack::Attack Moderate Throttling Example Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/configuration.md Example configuration for moderate public API throttling, allowing 15 requests per 30 seconds. ```env RACK_ATTACK_LIMIT=15 RACK_ATTACK_PERIOD=30 # 15 requests/30 seconds ``` -------------------------------- ### MySQL2 Database Connection String Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/configuration.md Example MySQL2 connection strings for database configuration. Ensure the 'mysql2://' schema is used. ```bash mysql2://user:password@localhost/bible_api ``` ```bash mysql2://root:password@127.0.0.1:3306/bible_api ``` -------------------------------- ### Translation Example Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/types.md Example JSON response for a Bible translation. ```json { "identifier": "web", "name": "World English Bible", "language": "English", "language_code": "eng", "license": "Public Domain", "url": "https://bible-api.com/data/web" } ``` -------------------------------- ### Preventing Brute Force Scanning Example Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/api-reference/abuse_middleware.md Shows an example of automated attempts to discover verses by making requests to random paths. ```http GET /random1, /random2, /random3, ... (automated attempts) ``` -------------------------------- ### Prevention Strategy: Use /data Endpoints Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/errors.md This example shows how to fetch data like all books at once using a `/data` endpoint, which is more efficient than making multiple individual calls. ```ruby # Get all books at once instead of multiple calls books_response = HTTP.get("https://bible-api.com/data/web") books = books_response.json['books'] ``` -------------------------------- ### Configure Abuse Middleware (Strict) Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/api-reference/abuse_middleware.md Example of configuring the Abuse Middleware with strict settings, recommended for production environments. ```ruby use Rack::AbuseMiddleware, redis: REDIS, limit: 5, window: 30, block_time: 7200 ``` -------------------------------- ### Load Environment Variables with Dotenv Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/configuration.md Example .env file format for loading environment variables. System variables take precedence, and comments are ignored. ```env DATABASE_URL=mysql2://user:password@localhost/bible_api REDIS_URL=redis://localhost:6379 PORT=5000 RACK_ENV=production RACK_ATTACK_LIMIT=15 RACK_ATTACK_PERIOD=30 WEB_CONCURRENCY=2 RAILS_MAX_THREADS=3 ``` -------------------------------- ### Verse Reference Endpoint Response Example Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/endpoints.md Example JSON response for a successful request to the verse reference endpoint, including reference details, verse text, and translation information. ```json { "reference": "John 3:16", "verses": [ { "book_id": "JHN", "book_name": "John", "chapter": 3, "verse": 16, "text": "\nFor God so loved the world, that he gave his one and only Son, that whoever believes in him should not perish, but have eternal life.\n\n" } ], "text": "\nFor God so loved the world, that he gave his one and only Son, that whoever believes in him should not perish, but have eternal life.\n\n", "translation_id": "web", "translation_name": "World English Bible", "translation_note": "Public Domain" } ``` -------------------------------- ### Development Environment Configuration Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/configuration.md Environment variables for the development setup. Enables Sinatra auto-reloader and detailed error pages. ```env RACK_ENV=development DATABASE_URL=mysql2://root:password@localhost/bible_api_dev REDIS_URL=redis://localhost:6379 PORT=5000 WEB_CONCURRENCY=1 RAILS_MAX_THREADS=3 RACK_ATTACK_LIMIT=100 RACK_ATTACK_PERIOD=30 ``` -------------------------------- ### Redis Connection String Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/configuration.md Example Redis connection strings for caching and rate limiting. The server must be accessible from the application server. ```bash redis://localhost:6379 ``` ```bash redis://user:password@redis.example.com:6379/0 ``` ```bash redis://redis.internal:6379 ``` -------------------------------- ### Run the Bible API Application Source: https://github.com/seven1m/bible_api/blob/master/README.md Start the bible_api application for testing purposes using the command 'bundle exec ruby app.rb'. For production, consider using Passenger. ```sh bundle exec ruby app.rb ``` -------------------------------- ### Configure Abuse Middleware (Lenient) Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/api-reference/abuse_middleware.md Example of configuring the Abuse Middleware with lenient settings, suitable for development or testing environments. ```ruby use Rack::AbuseMiddleware, redis: REDIS, limit: 100, window: 60, block_time: 60 ``` -------------------------------- ### Rack::AbuseMiddleware Unit Test Example Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/api-reference/abuse_middleware.md A unit test for Rack::AbuseMiddleware demonstrating how to mock requests and assert blocking behavior after exceeding the 404 limit. ```ruby require 'redis' require_relative '../lib/abuse_middleware' describe Rack::AbuseMiddleware do let(:app) { ->(env) { [200, {}, ['OK']] } } let(:redis) { Redis.new } let(:middleware) do Rack::AbuseMiddleware.new(app, redis: redis, limit: 3, window: 10, block_time: 60) end before do redis.flushdb # Clear Redis before each test end it 'blocks IP after exceeding 404 limit' do env = { 'REMOTE_ADDR' => '192.168.1.1', 'REQUEST_METHOD' => 'GET', 'PATH_INFO' => '/test' } # First 3 404s - allowed 3.times do app_response = [404, {}, ['Not Found']] allow(app).to receive(:call).and_return(app_response) status, _, _ = middleware.call(env) expect(status).to eq(404) end # 4th 404 - blocked allow(app).to receive(:call).and_return([404, {}, ['Not Found']]) status, _, body = middleware.call(env) expect(status).to eq(403) expect(body).to eq(['Forbidden\n']) end it 'allows non-404 responses' do env = { 'REMOTE_ADDR' => '192.168.1.2', 'REQUEST_METHOD' => 'GET', 'PATH_INFO' => '/test' } allow(app).to receive(:call).and_return([200, {}, ['OK']]) 10.times do status, _, _ = middleware.call(env) expect(status).to eq(200) end end it 'extracts IP from X-Forwarded-For header' do env = { 'HTTP_X_FORWARDED_FOR' => '10.0.0.1, 10.0.0.2', 'REMOTE_ADDR' => '192.168.1.1', 'REQUEST_METHOD' => 'GET' } allow(app).to receive(:call).and_return([404, {}, ['Not Found']]) # The middleware uses the first IP from X-Forwarded-For # Verifiable by checking Redis keys middleware.call(env) expect(redis.exists('ips:10.0.0.1:404s')).to eq(1) end end ``` -------------------------------- ### Get Bible Chapter Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/endpoints.md Retrieves an entire chapter of the Bible. Use the book name and chapter number in the reference. ```bash curl https://bible-api.com/Psalm+23 ``` -------------------------------- ### Protecting Against Invalid Reference Spam Example Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/api-reference/abuse_middleware.md Demonstrates how the middleware prevents clients from spamming the server with malformed references. ```http GET /foo, /bar, /baz, /qux, ... (invalid books/chapters) ``` -------------------------------- ### Production Environment Configuration Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/configuration.md Environment variables for the production setup. Enables rate limiting and abuse prevention for scaled traffic. ```env RACK_ENV=production DATABASE_URL=mysql2://app_user:secure_password@db.example.com/bible_api REDIS_URL=redis://redis.example.com:6379 PORT=3000 WEB_CONCURRENCY=4 RAILS_MAX_THREADS=5 RACK_ATTACK_LIMIT=15 RACK_ATTACK_PERIOD=30 ``` -------------------------------- ### Test Environment Configuration Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/configuration.md Environment variables for the test setup. Rack::Attack is disabled, and a separate Redis namespace is used. ```env RACK_ENV=test DATABASE_URL=mysql2://root:password@localhost/bible_api_test REDIS_URL=redis://localhost:6379/1 ``` -------------------------------- ### List Available Translations using cURL Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/README.md Demonstrates how to list all available Bible translations by making a GET request to the `/data` endpoint. ```bash # List translations curl https://bible-api.com/data ``` -------------------------------- ### Prevention Strategy: Batch Requests Efficiently Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/errors.md This example contrasts inefficiently making many individual requests with a more efficient approach that spaces out requests to avoid hitting rate limits. ```ruby # Instead of: 15.times do HTTP.get("https://bible-api.com/random") end # Use: 5.times do HTTP.get("https://bible-api.com/data/web/random") sleep(2) # Space out requests end ``` -------------------------------- ### Drop Tables and Reimport Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/api-reference/database.md Employs the '--drop-tables' flag to remove all existing database tables before starting the import process. ```bash ruby import.rb --drop-tables ``` -------------------------------- ### Get Chapter Listing Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/endpoints.md Fetch a list of all chapters for a given book within a specific translation. Requires the translation identifier and the 3-character book ID. ```http GET /data/web/JHN GET /data/kjv/GEN ``` -------------------------------- ### Get Bible Verse Range Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/endpoints.md Retrieves a range of Bible verses. Specify the start and end verses within the reference. ```bash curl https://bible-api.com/John+3:16-17 ``` -------------------------------- ### 404 Not Found Response Examples Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/errors.md These JSON structures indicate a 'not found' error, with specific messages detailing the cause such as invalid verse, translation, book, or chapter. ```json { "error": "not found" } ``` ```json { "error": "translation not found" } ``` ```json { "error": "book not found" } ``` ```json { "error": "book/chapter not found" } ``` -------------------------------- ### Initialize Application Connections Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/api-reference/app.md Sets up essential application connections to Redis and the database upon startup. Configures rate limiting parameters. ```ruby REDIS = Redis.new(url: ENV.fetch('REDIS_URL')) DB = Sequel.connect(ENV.fetch('DATABASE_URL').sub(%r{mysql://}, 'mysql2://'), encoding: 'utf8mb4', max_connections: 10) RACK_ATTACK_LIMIT = ENV.fetch('RACK_ATTACK_LIMIT', 15).to_i RACK_ATTACK_PERIOD = ENV.fetch('RACK_ATTACK_PERIOD', 30).to_i ``` -------------------------------- ### GET / Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/endpoints.md Serves an HTML index page or a random Bible verse if the 'random' query parameter is set to true. The index page lists available translations and documentation. ```APIDOC ## GET / ### Description Serves an HTML index page or a random Bible verse if the 'random' query parameter is set to true. The index page lists available translations and supporting documentation. ### Method GET ### Endpoint / ### Query Parameters - **random** (string, optional): When set to `true`, returns a random verse instead of the HTML page. ### Response #### Success Response (200 OK) - Without `random` parameter: HTML page listing available translations and supporting documentation. #### Success Response (200 OK) - With `random=true`: Same structure as the verse endpoint (`GET /:ref`) with a randomly selected verse. ``` -------------------------------- ### Create Database and Import Translations Source: https://github.com/seven1m/bible_api/blob/master/README.md Set up the MySQL database for bible_api and import the translation data using the provided import script. Ensure DATABASE_URL and REDIS_URL are exported. ```sh mysql -uroot -e "create database bible_api; grant all on bible_api.* to user@localhost identified by 'password';" export DATABASE_URL="mysql2://user:password@localhost/bible_api" export REDIS_URL="redis://localhost:6379" bundle exec ruby import.rb ``` -------------------------------- ### Handling 404 Errors in Ruby Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/errors.md This Ruby code demonstrates how to make an HTTP GET request and handle a 404 status code by parsing the JSON response to identify the specific error. ```ruby response = HTTP.get("https://bible-api.com/John+3:16?translation=kjv") if response.status == 404 data = JSON.parse(response.body) case data['error'] when 'not found' puts "Invalid verse reference" when 'translation not found' puts "Translation not available" # Fall back to default translation response = HTTP.get("https://bible-api.com/John+3:16") when 'book not found' puts "Book not in translation" end end ``` -------------------------------- ### Application Initialization Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/api-reference/app.md Initializes global constants for Redis and the database connection using environment variables. Sets up the Sequel database connection with UTF8MB4 encoding and a maximum of 10 connections. ```ruby require 'bundler' Bundler.require REDIS = Redis.new(url: ENV.fetch('REDIS_URL')) DB = Sequel.connect( ENV.fetch('DATABASE_URL').sub(%r{mysql://}, 'mysql2://'), encoding: 'utf8mb4', max_connections: 10 ) ``` -------------------------------- ### Get Random Verse from Translation Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/endpoints.md Fetch a random verse from a specified translation using the GET /data/:translation/random endpoint. This is useful for quick access to verse content. ```http GET /data/web/random GET /data/kjv/random ``` -------------------------------- ### Get Chapters in a Specific Book using cURL Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/README.md Illustrates how to get a list of chapters for a specific book within a translation by querying the `/data/:translation/:book_id` endpoint. ```bash # Get chapters in book curl https://bible-api.com/data/web/JHN ``` -------------------------------- ### Show Help Message Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/api-reference/database.md Displays the help information for the 'import.rb' script using the '-h' or '--help' flag. ```bash ruby import.rb -h ``` -------------------------------- ### Import Bible Translations with Options Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/configuration.md Demonstrates how to use the import.rb script with various command-line options to control which translations are imported, the path to the Bible data, and whether to overwrite existing data or drop tables. ```bash ruby import.rb [options] ``` ```bash # Import all translations ruby import.rb ``` ```bash # Import only World English Bible ruby import.rb -t eng-web.osis.xml ``` ```bash # Use custom bibles directory ruby import.rb --bibles-path=/path/to/open-bibles ``` ```bash # Drop tables and reimport everything ruby import.rb --drop-tables ``` ```bash # Overwrite existing translations ruby import.rb --overwrite ``` -------------------------------- ### Get Translation Metadata and Book List Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/endpoints.md Retrieve metadata and a list of books for a specific translation using the GET /data/:translation endpoint. The 'translation' parameter can also be specified as a query parameter. ```http GET /data/web GET /data/kjv GET /data/cuv ``` -------------------------------- ### Verse Reference Response Structure Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/types.md The main response type for verse reference requests. It includes the normalized reference, an array of Verse objects, concatenated text, and translation details. Used for GET /:ref and GET /?random=true. ```json { "reference": "John 3:16-17", "verses": [ { "book_id": "JHN", "book_name": "John", "chapter": 3, "verse": 16, "text": "For God so loved the world..." }, { "book_id": "JHN", "book_name": "John", "chapter": 3, "verse": 17, "text": "For God did not send his Son..." } ], "text": "For God so loved the world... For God did not send his Son...", "translation_id": "web", "translation_name": "World English Bible", "translation_note": "Public Domain" } ``` -------------------------------- ### Configuration Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/DOCUMENTATION_INDEX.txt Details all environment variables and configuration options for setting up and tuning the Bible API, including database connection and rate limiting. ```APIDOC ## Configuration This section outlines the configuration options and environment variables required to set up, run, and tune the Bible API. ### Environment Variables - **Required Variables**: Details on essential variables like database credentials and API keys. - **Optional Variables**: Configuration for features like rate limiting, logging levels, and cache settings. ### Database Setup - Instructions for connecting to the database, including connection strings and required schema setup. ### Rate Limiting - Configuration parameters for rate limiting, including limits per IP, time windows, and response codes. ### Example Configuration Snippet ```ruby # Example environment variable settings: # DB_HOST=localhost # DB_PORT=5432 # DB_NAME=bible_api_db # RATE_LIMIT_PER_MINUTE=100 ``` ``` -------------------------------- ### Get Random Verse Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/README.md Retrieves a random verse from the Bible for a specified translation. ```APIDOC ## GET /data/:translation/random ### Description Retrieves a random verse from the specified translation. ### Method GET ### Endpoint `/data/:translation/random` ### Parameters #### Path Parameters - **translation** (string) - Required - The identifier of the translation (e.g., `web`, `kjv`). ### Response #### Success Response (200) Returns a JSON object containing a random verse and its details. #### Response Example ```json { "reference": "Psalm 119:105", "verses": [ { "book_id": "PSA", "book_name": "Psalm", "chapter": 119, "verse": 105, "text": "Your word is a lamp to my feet and a light on my path." } ], "text": "Your word is a lamp to my feet and a light on my path.", "translation_id": "web", "translation_name": "World English Bible", "translation_note": "Public Domain" } ``` ``` -------------------------------- ### Required Environment Variables for Deployment Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/README.md Lists essential environment variables for deploying the Bible API. Includes database connection and Redis URL configurations. ```bash DATABASE_URL=mysql2://user:password@localhost/bible_api REDIS_URL=redis://localhost:6379 ``` -------------------------------- ### Explain SQL Query Plan Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/api-reference/database.md Shows the execution plan for a specific SQL query, useful for understanding performance bottlenecks. ```sql EXPLAIN SELECT * FROM verses WHERE book_id = 'JHN' AND chapter = 3 AND translation_id = 1 ``` -------------------------------- ### Get Verses in Chapter Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/README.md Retrieves all verses for a specific chapter of a book within a given translation. ```APIDOC ## GET /data/:translation/:book_id/:chapter ### Description Retrieves all verses for a specific chapter of a book within the specified translation. ### Method GET ### Endpoint `/data/:translation/:book_id/:chapter` ### Parameters #### Path Parameters - **translation** (string) - Required - The identifier of the translation (e.g., `web`, `kjv`). - **book_id** (string) - Required - The identifier of the book (e.g., `JHN`, `PSA`). - **chapter** (integer) - Required - The chapter number. ### Response #### Success Response (200) Returns a JSON object containing the reference, verses, and translation details for the specified chapter. #### Response Example ```json { "reference": "John 3", "verses": [ { "book_id": "JHN", "book_name": "John", "chapter": 3, "verse": 1, "text": "There was a man of the Pharisees, named Nicodemus..." }, ... ], "text": "There was a man of the Pharisees, named Nicodemus...", "translation_id": "web", "translation_name": "World English Bible", "translation_note": "Public Domain" } ``` ``` -------------------------------- ### Get Chapters in Book Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/README.md Retrieves a list of chapters for a specific book within a given translation. ```APIDOC ## GET /data/:translation/:book_id ### Description Retrieves a list of chapters for a specific book within the specified translation. ### Method GET ### Endpoint `/data/:translation/:book_id` ### Parameters #### Path Parameters - **translation** (string) - Required - The identifier of the translation (e.g., `web`, `kjv`). - **book_id** (string) - Required - The identifier of the book (e.g., `JHN`, `PSA`). ### Response #### Success Response (200) Returns a JSON object containing the book ID and a list of chapters. #### Response Example ```json { "book_id": "JHN", "chapters": [ { "chapter": 1, "verses": 38 }, { "chapter": 2, "verses": 25 }, ... ] } ``` ``` -------------------------------- ### Configure Database Connection with Sequel Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/api-reference/database.md Sets up the database connection using the Sequel ORM in Ruby. It fetches the DATABASE_URL from environment variables and transforms MySQL URLs for compatibility. Ensures UTF-8MB4 character set and limits connections to 10. ```ruby DB = Sequel.connect( ENV.fetch('DATABASE_URL').sub(%r{mysql://}, 'mysql2://'), encoding: 'utf8mb4', max_connections: 10 ) ``` -------------------------------- ### Get a random verse from a translation Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/endpoints.md Retrieves a single, randomly selected verse from a specified Bible translation. ```APIDOC ## GET /data/:translation/random ### Description Get a random verse from a translation. ### Method GET ### Endpoint /data/:translation/random ### Parameters #### Path Parameters - `translation` (string, required): Translation identifier ### Response (200 OK) ```json { "translation": { "identifier": "web", "name": "World English Bible", "language": "English", "language_code": "eng", "license": "Public Domain" }, "random_verse": { "book_id": "MAT", "book": "Matthew", "chapter": 5, "verse": 3, "text": "Blessed are the poor in spirit, for theirs is the kingdom of heaven." } } ``` ### Response Fields: - `translation` (object) - Translation metadata - `random_verse` (object) - Single randomly selected verse - `random_verse.book_id` (string) - 3-character book ID - `random_verse.book` (string) - Localized book name - `random_verse.chapter` (integer) - Chapter number - `random_verse.verse` (integer) - Verse number - `random_verse.text` (string) - Verse text **Error Responses:** - 404: Invalid translation or no verses available. Response: `{ error: "translation not found" }` or `{ error: "error getting verse" }` ``` -------------------------------- ### Sample Data for 'verses' Table Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/api-reference/database.md Illustrates the structure and content of rows within the 'verses' table, showing verse details and associated metadata. ```sql | id | book_num | book_id | book | chapter | verse | text | translation_id | |------|----------|---------|------|---------|-------|----------------------|----------------| | 1 | 1 | GEN | Gen. | 1 | 1 | In the beginning... | 1 | | 2 | 1 | GEN | Gen. | 1 | 2 | The earth was... | 1 | | 12345| 43 | JHN | John | 3 | 16 | For God so loved... | 1 | | 12346| 43 | JHN | John | 3 | 17 | For God did not... | 1 | ``` -------------------------------- ### Get Translation Metadata and Books Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/README.md Retrieves metadata for a specific translation, including a list of books available in that translation. ```APIDOC ## GET /data/:translation ### Description Retrieves metadata for a specific translation and a list of books within that translation. ### Method GET ### Endpoint `/data/:translation` ### Parameters #### Path Parameters - **translation** (string) - Required - The identifier of the translation (e.g., `web`, `kjv`). ### Response #### Success Response (200) Returns a JSON object containing translation metadata and a list of books. #### Response Example ```json { "translation_id": "web", "translation_name": "World English Bible", "books": [ { "book_id": "GEN", "book_name": "Genesis" }, { "book_id": "EXO", "book_name": "Exodus" }, ... ] } ``` ``` -------------------------------- ### Basic Import Command Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/api-reference/database.md Executes the 'import.rb' script to load all Bible translations found in the default './bibles' directory. ```bash ruby import.rb ``` -------------------------------- ### Error Handling Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/DOCUMENTATION_INDEX.txt Comprehensive guide to HTTP status codes, error conditions, and recovery strategies for the Bible API. ```APIDOC ## Error Handling This section details the error handling mechanisms within the Bible API, including supported HTTP status codes, common error conditions, and recommended recovery strategies. ### HTTP Status Codes - **200 OK**: Standard success response. - **400 Bad Request**: Invalid input or malformed request. - **403 Forbidden**: Insufficient permissions or unauthorized access. - **404 Not Found**: Requested resource does not exist. - **429 Too Many Requests**: Rate limit exceeded. ### Error Conditions - Specific triggers for each error code, such as invalid query parameters, non-existent resources, or authentication failures. ### Recovery Strategies - Guidance on how clients should respond to errors, including retry mechanisms and debugging tips. ### Example Error Response ```json { "error": { "status": 404, "message": "The requested translation ID was not found." } } ``` ``` -------------------------------- ### Rack::AbuseMiddleware Constructor Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/api-reference/abuse_middleware.md Initializes the AbuseMiddleware with a wrapped Rack application and configuration options. It sets up parameters for rate limiting 404 requests and blocking abusive IPs. ```APIDOC ## initialize(app, options = {}) ### Description Initializes the Rack::AbuseMiddleware with a wrapped Rack application and configuration options. It sets up parameters for rate limiting 404 requests and blocking abusive IPs. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **app** (Rack app) - Required - The wrapped Rack application. - **options[:redis]** (Redis client) - Required - Redis connection for storing blocked IPs. - **options[:limit]** (Integer) - Optional - Number of 404s allowed before blocking. Defaults to 10. - **options[:window]** (Integer) - Optional - Time window in seconds for counting 404s. Defaults to 30. - **options[:block_time]** (Integer) - Optional - Duration in seconds to block IP. Defaults to 3600 (1 hour). ### Request Example ```ruby use Rack::AbuseMiddleware, redis: Redis.new, limit: 10, window: 30, block_time: 3600 ``` ### Response N/A (Constructor does not return a response in the typical API sense.) ### Error Handling N/A ``` -------------------------------- ### Constructor for Rack::AbuseMiddleware Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/api-reference/abuse_middleware.md Initializes the middleware with the wrapped Rack application and configuration options. Sets up Redis connection, 404 limit, time window, and block duration. ```ruby def initialize(app, options = {}) @app = app @redis = options.fetch(:redis) @limit = options[:limit] || 10 @window = options[:window] || 30 @block_time = options[:block_time] || 3600 end ``` -------------------------------- ### Get Random Verse from Specific Book/Testament Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/README.md Retrieves a random verse from a specific book or testament within a given translation. ```APIDOC ## GET /data/:translation/random/:book_id ### Description Retrieves a random verse from a specific book or testament within the specified translation. ### Method GET ### Endpoint `/data/:translation/random/:book_id` ### Parameters #### Path Parameters - **translation** (string) - Required - The identifier of the translation (e.g., `web`, `kjv`). - **book_id** (string) - Required - The identifier of the book (e.g., `JHN`, `OT` for Old Testament, `NT` for New Testament). ### Response #### Success Response (200) Returns a JSON object containing a random verse from the specified book/testament and its details. #### Response Example ```json { "reference": "Genesis 1:1", "verses": [ { "book_id": "GEN", "book_name": "Genesis", "chapter": 1, "verse": 1, "text": "In the beginning, God created the heavens and the earth." } ], "text": "In the beginning, God created the heavens and the earth.", "translation_id": "web", "translation_name": "World English Bible", "translation_note": "Public Domain" } ``` ``` -------------------------------- ### GET /data/:translation Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/errors.md Retrieves metadata for a specific Bible translation. This endpoint is useful for checking the validity of a translation ID. ```APIDOC ## GET /data/:translation ### Description Retrieves information about a specific Bible translation. ### Method GET ### Endpoint `/data/:translation` ### Parameters #### Path Parameters - **translation** (string) - Required - The ID of the translation to retrieve information for. ### Possible Errors - `translation not found`: Invalid translation ID. HTTP Status: 404 ### Response #### Success Response (200) - (JSON object) - Contains details about the translation, including its ID, name, and available books. #### Response Example ```json { "id": "web", "name": "World English Bible", "books": [ { "id": "gen", "name": "Genesis", "chapters": 50 }, { "id": "exo", "name": "Exodus", "chapters": 40 }, ... ] } ``` ``` -------------------------------- ### Clone the bible_api Repository Source: https://github.com/seven1m/bible_api/blob/master/README.md Clone the git repository for the bible_api project. This is the first step in self-hosting the application. ```sh git clone https://github.com/seven1m/bible_api cd bible_api git submodule update --init ``` -------------------------------- ### Helper Functions Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/DOCUMENTATION_INDEX.txt Documentation for seven custom helper functions used within the application, including their signatures, purpose, and usage. ```APIDOC ## Helper Functions This section details the custom helper functions available within the application, providing their exact type signatures and explanations for their usage. ### Functions Documented - **get_verse_id()**: Converts a Bible reference string into a unique verse ID. - **get_verses()**: Retrieves verse data based on provided references and translation. - **get_translation()**: Fetches details about a specific Bible translation. - **translation_as_json()**: Serializes translation data into JSON format. - **render_response()**: Formats and renders the API response. - **single_chapter_book_matching()**: Logic for handling books with a single chapter. - **display_verse_from()**: Utility for displaying verse content. ### Example Function Signature ```ruby # Signature: get_verses(reference: String, translation_id: String, options: Hash = {}) # Description: Retrieves a collection of verses based on a given reference string and translation ID. Supports various options for filtering and formatting. ``` ``` -------------------------------- ### Create Verses Table Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/configuration.md SQL statement to create the 'verses' table, including columns for book, chapter, verse text, and translation ID. ```sql CREATE TABLE verses ( id INT PRIMARY KEY AUTO_INCREMENT, book_num INT, book_id VARCHAR(10), book VARCHAR(255), chapter INT, verse INT, text LONGTEXT, translation_id INT, KEY (translation_id), KEY (book_id, chapter) ) CHARSET=utf8mb4; ``` -------------------------------- ### Disabling Rack::Attack in Tests Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/api-reference/abuse_middleware.md Provides an example of how to disable Rack::Attack during test suites, while noting that AbuseMiddleware remains active. ```ruby # spec/spec_helper.rb config.before(:suite) { Rack::Attack.enabled = false } ``` -------------------------------- ### Rack::AbuseMiddleware Integration with Sinatra Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/api-reference/abuse_middleware.md Shows how to integrate Rack::AbuseMiddleware into a Sinatra application, including configuration for Redis, limit, window, and block time. ```ruby require_relative './lib/abuse_middleware' use Rack::Attack Rack::Attack.cache.store = Rack::Attack::StoreProxy::RedisStoreProxy.new(REDIS) Rack::Attack.throttle('requests by ip', limit: RACK_ATTACK_LIMIT, period: RACK_ATTACK_PERIOD) { |request| request.ip } use Rack::AbuseMiddleware, redis: REDIS, limit: 10, window: 30, block_time: 3600 ``` -------------------------------- ### GET /data/:translation/:book_id/:chapter Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/endpoints.md Retrieves all verses for a specific chapter in a given translation and book. Verses are returned in order. ```APIDOC ## GET /data/:translation/:book_id/:chapter ### Description Get all verses in a specific chapter. ### Method GET ### Endpoint /data/:translation/:book_id/:chapter ### Parameters #### Path Parameters - **translation** (string) - Required - Translation identifier - **book_id** (string) - Required - 3-character book ID - **chapter** (integer) - Required - Chapter number ### Response #### Success Response (200 OK) - **translation** (object) - Translation metadata - **verses** (array) - Array of verses in the chapter, each with `book_id`, `book`, `chapter`, `verse`, and `text`. ### Response Example ```json { "translation": { ... }, "verses": [ { "book_id": "JHN", "book": "John", "chapter": 3, "verse": 1, "text": "Now there was a Pharisee named Nicodemus, a ruler of the Jews." } ] } ``` #### Response Fields - `translation` (object) - Translation metadata - `verses` (array) - Array of verses in the chapter - `verses[].book_id` (string) - 3-character book ID - `verses[].book` (string) - Localized book name - `verses[].chapter` (integer) - Chapter number - `verses[].verse` (integer) - Verse number - `verses[].text` (string) - Verse text **Ordering:** Verses ordered by chapter and verse number. #### Error Responses - **404** - Invalid translation, book, or chapter. Response: `{ error: "book/chapter not found" }` ``` -------------------------------- ### OPTIONS /:ref Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/endpoints.md Handles CORS preflight requests for the /:ref endpoint. Returns CORS headers only, with no response body. ```APIDOC ## OPTIONS /:ref ### Description CORS preflight request handler for the /:ref endpoint. Returns CORS headers only, with no response body. ### Method OPTIONS ### Endpoint /:ref ### Response #### Success Response (200 OK) - Returns CORS headers only, no body ``` -------------------------------- ### Manage Dokku MySQL Database Source: https://github.com/seven1m/bible_api/blob/master/DOKKU.md Commands for creating, linking, importing data into, promoting, and cleaning up Dokku MySQL databases. Ensure to use the correct environment variable for database URL during import. ```sh dokku mysql:create bible_api_2024 dokku mysql:link bible_api_2024 bible-api.com dokku enter bible-api.com DATABASE_URL="$DOKKU_MYSQL_AQUA_URL" ruby import.rb # or whatever env var Dokku gave you exit dokku mysql:promote bible_api_2024 bible-api.com # verify nothing broken dokku mysql:unlink bible_2023 bible-api.com dokku mysql:stop bible_2023 dokku mysql:destroy bible_2023 ``` -------------------------------- ### GET /data/:translation/:book_id/:chapter Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/errors.md Retrieves information about a specific chapter within a book and translation, including the number of verses. ```APIDOC ## GET /data/:translation/:book_id/:chapter ### Description Retrieves information about a specific chapter within a book and translation. ### Method GET ### Endpoint `/data/:translation/:book_id/:chapter` ### Parameters #### Path Parameters - **translation** (string) - Required - The ID of the translation. - **book_id** (string) - Required - The ID of the book. - **chapter** (integer) - Required - The chapter number. ### Possible Errors - `translation not found`: Invalid translation ID. HTTP Status: 404 - `book/chapter not found`: Invalid book or chapter number for the specified translation. HTTP Status: 404 ### Response #### Success Response (200) - (JSON object) - Contains details about the chapter, including the number of verses. #### Response Example ```json { "book": "John", "chapter": 3, "verses": 21, "translation": "web" } ``` ``` -------------------------------- ### Enable Database and Sinatra Request Logging Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/errors.md Configure detailed logging for database queries and incoming requests by enabling debug logging for the database and setting Sinatra's logging to true. ```ruby # Database query logging DB.sql_log_level = :debug DB.loggers << Logger.new($stdout) # Sinatra request logging set :logging, true ``` -------------------------------- ### GET /data/:translation/:book_id Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/errors.md Retrieves information about a specific book within a given Bible translation, including the number of chapters. ```APIDOC ## GET /data/:translation/:book_id ### Description Retrieves information about a specific book within a given Bible translation. ### Method GET ### Endpoint `/data/:translation/:book_id` ### Parameters #### Path Parameters - **translation** (string) - Required - The ID of the translation. - **book_id** (string) - Required - The ID of the book (e.g., 'gen', 'exo'). ### Possible Errors - `translation not found`: Invalid translation ID. HTTP Status: 404 - `book not found`: Book ID not found in the specified translation. HTTP Status: 404 ### Response #### Success Response (200) - (JSON object) - Contains details about the book, including its ID, name, and the number of chapters. #### Response Example ```json { "id": "gen", "name": "Genesis", "chapters": [ { "chapter": 1, "verses": 31 }, { "chapter": 2, "verses": 25 }, ... ] } ``` ``` -------------------------------- ### Set Rack Environment Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/configuration.md Set the environment mode for the application (e.g., development, production, test). Behavior, caching, and logging vary by environment. ```bash RACK_ENV=production ``` ```bash RACK_ENV=development ``` ```bash RACK_ENV=test ``` -------------------------------- ### Get New Testament Books Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/api-reference/app.md Retrieves an array of the last 27 New Testament book IDs from the Protestant canon. This is a cached property. ```ruby def nt_books @nt_books ||= protestant_books[protestant_books.index('MAT')..] end ``` -------------------------------- ### Get Old Testament Books Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/api-reference/app.md Retrieves an array of the first 39 Old Testament book IDs from the Protestant canon. This is a cached property. ```ruby def ot_books @ot_books ||= protestant_books[...protestant_books.index('MAT')] end ``` -------------------------------- ### Configure Rate Limiting Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/README.md Customize the rate limiting thresholds by editing these lines in `app.rb` or by setting environment variables. ```ruby RACK_ATTACK_LIMIT = ENV.fetch('RACK_ATTACK_LIMIT', 15).to_i RACK_ATTACK_PERIOD = ENV.fetch('RACK_ATTACK_PERIOD', 30).to_i ``` -------------------------------- ### Get Specific Verse Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/README.md Retrieves a specific verse or range of verses from the Bible. You can specify the translation and whether to include verse numbers in the response. ```APIDOC ## GET /:ref ### Description Retrieves a specific verse or range of verses by reference. Supports various reference formats and allows specifying the translation. ### Method GET ### Endpoint `/:ref` ### Parameters #### Query Parameters - **translation** (string) - Optional - The translation to use (e.g., `kjv`, `web`). - **verse_numbers** (boolean) - Optional - Whether to include verse numbers in the response. ### Request Example ```bash curl https://bible-api.com/John+3:16?translation=kjv&verse_numbers=true ``` ### Response #### Success Response (200) Returns a JSON object containing the requested verse(s), translation information, and reference details. #### Response Example ```json { "reference": "John 3:16", "verses": [ { "book_id": "JHN", "book_name": "John", "chapter": 3, "verse": 16, "text": "For God so loved the world..." } ], "text": "For God so loved the world...", "translation_id": "web", "translation_name": "World English Bible", "translation_note": "Public Domain" } ``` ``` -------------------------------- ### Optional Configuration Environment Variables Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/README.md Outlines optional environment variables for customizing API behavior, such as port, environment mode, rate limiting, and worker/thread counts. ```bash PORT=5000 # HTTP port (default: 5000) RACK_ENV=production # Environment mode RACK_ATTACK_LIMIT=15 # Requests per period (default: 15) RACK_ATTACK_PERIOD=30 # Period in seconds (default: 30) WEB_CONCURRENCY=2 # Puma workers (default: 2) RAILS_MAX_THREADS=3 # Threads per worker (default: 3) ``` -------------------------------- ### Run RSpec Tests Source: https://github.com/seven1m/bible_api/blob/master/_autodocs/README.md Execute the project's test suite using RSpec with this command. ```bash bundle exec rspec ```