APICraft Rails

Build Gem Version

๐Ÿš€ Accelerates your development by 2-3x with an API Design First approach. Seamlessly integrates with your Rails application server โ€” no fancy tooling or expenses required.

We believe that API contracts should lead the development process, not be an afterthought derived from code. This framework embraces the API Design-First philosophy, ensuring that contracts remain independent from implementation.

With APICraft, contracts are not only clear and consistent, but theyโ€™re also immediately usable, enabling teams to work with automatically generated mocks, behaviours and introspection tools, allowing development to begin in parallel, without waiting for backend implementations.

It avoids the pitfalls of the code-first methodology, where contracts are auto-generated, often leading to inconsistency and misalignment.

APICraft Rails Logo

โœจ Features

  • ๐Ÿ›ก๏ธ Automatic Request Validations - Validates the request based on the openapi specs so that you don't need to add params validations everywhere in your controllers.

  • ๐Ÿง‘โ€๐Ÿ’ป๏ธ Dynamic Mock Data Generation - Detects the specifications and instantly mounts working routes with mock responses. No extra configuration required.

  • โš™๏ธ Customizable Mock Responses - Tailor mock responses to simulate different scenarios and edge cases, helping your team prepare for real-world conditions right from the start.

  • ๐Ÿ” API Introspections - Introspect API schemas without needing to dig into the docs everytime.

  • ๐Ÿ“บ Documentation Out of the Box - Documentation using SwaggerDoc and RapiDoc both.

  • ๐Ÿ—‚ Easy Contracts Management - Management of openapi specifications from within app/contracts directory. No new syntax, just plain old openapi standard with .json or .yaml formats

๐Ÿ”œ Upcoming Features

  • ๐Ÿ’Ž Clean & Custom Ruby DSL - Support for a Ruby DSL alongwith the current .json and .yaml formats.

๐Ÿช„ Works Like Magic

Once youโ€™ve installed the gem, getting started is a breeze. Simply create your OpenAPI contracts within the app/contracts directory of your Rails application. Youโ€™re free to organize this directory in a way that aligns with your project's standards and preferences. Thatโ€™s itโ€”your APIs will be up and running with mock responses, ready for development without any additional setup. It's as effortless as it sounds!

๐Ÿ•Š API Design First Philosophy

APICraft Rails Logo

The API Design First philosophy is at the heart of APICraft Rails, and itโ€™s a game-changer for development speed and efficiency:

  • ๐Ÿ”„ Parallel Development: By designing your APIs upfront, both frontend and backend teams can work simultaneously using mock APIs, eliminating bottlenecks and reducing wait times.

  • ๐Ÿ“œ Clear Contracts: OpenAPI contracts serve as a single source of truth, ensuring that all teams are aligned on how the API should behave, reducing misunderstandings and rework.

  • โš™๏ธ Early Testing: Mock APIs allow QA to begin testing earlier in the development cycle, catching issues before they become costly to fix.

  • ๐Ÿ” Faster Feedback Loop: Immediate feedback on API design helps you iterate quickly, refining your API based on real usage scenarios, ultimately leading to a more robust product.

  • ๐Ÿš€ Reduced Integration Time: With consistent API contracts in place, integrating various components becomes smoother and faster, cutting down on the time required to bring everything together.

By adopting an API Design First approach with APICraft Rails, you can accelerate your development process by 2-3x, delivering high-quality APIs faster and with fewer headaches.

๐Ÿ— Installation

Add this line to your application's Gemfile:

gem 'apicraft-rails', '~> 1.0.0'

And then execute:

$ bundle install

After the installation in your rails project, you can start adding contracts in the app/contracts directory. This can have any internal directory structure based on your API versions, standards, etc.

Add the following into your Rails application, via the config/application.rb

# config/application.rb
module App
  class Application < Rails::Application
    # Rest of the configuration...

    [
      Apicraft::Middlewares::Mocker,
      Apicraft::Middlewares::Introspector,
      Apicraft::Middlewares::RequestValidator
    ].each { |mw| config.middleware.use mw }

    Apicraft.configure do |config|
      config.contracts_path = Rails.root.join("app/contracts")
    end
  end
end

Now every API in the specification has a functional version. For any path (from the contracts), APICraft serves a mock response when Apicraft-Mock: true is passed in the headers otherwise, it forwards the request to your application as usual.

โš™๏ธ Usage

Add your specification files to the app/contracts directory in your Rails project. You can also configure this directory to be something else.

my_rails_app/
โ”œโ”€โ”€ app/
โ”‚   โ”œโ”€โ”€ controllers/
โ”‚   โ”‚   โ”œโ”€โ”€ application_controller.rb
โ”‚   โ”‚   โ””โ”€โ”€ users_controller.rb
โ”‚   โ”œโ”€โ”€ contracts/
โ”‚   โ”‚   โ”œโ”€โ”€ users_contract.yaml
โ”‚   โ”‚   โ””โ”€โ”€ orders_contract.yaml
โ”‚   โ”œโ”€โ”€ models/
โ”‚   โ”‚   โ”œโ”€โ”€ user.rb
โ”‚   โ”‚   โ””โ”€โ”€ order.rb

๐Ÿ›ก๏ธ Request Validations

All incoming requests will be validated against the defined schema. This ensures that by the time the params reach the controller they are adhering to all the schema requirements. It's enabled by default. You can customize the response of a failed validation. Check the configuration section section for a full list of options for this.

๐ŸŽญ Mocking

APICraft dynamically generates mock APIs by interpreting contract specifications on the fly. You can request the mock response by passing Apicraft-Mock: true in the headers.

https://yoursite.com/api/orders

headers: {
  Apicraft-Mock: true
}
[
  {
    "id": 66,
    "name": "tempora",
    "description": "error"
  },
  {
    "id": 41,
    "name": "et",
    "description": "id"
  }
]

๐ŸŽฎ Behaviour Mocking

The above is an example of a 200 response. If you have more responses documented you can force that behaviour using Apicraft-Response-Code header in the mock request. You can find a list of all the supported headers in the configuration section that would allow you to manipulate the API Behaviour.

https://yoursite.com/api/orders

headers: {
  Apicraft-Response-Code: 400
  Apicraft-Mock: true
  Apicraft-Delay: 5
}
{
  "code": 400,
  "message": "Something's not right"
}

๐Ÿง Introspection

All APIs are can be introspected. You can do so by passing the Apicraft-Introspect header.

headers: {
  Apicraft-Introspect: true
}

Example: https://yoursite.com/api/orders

{
  "summary": "Retrieve a list of orders",
  "description": "Returns a list of orders in either JSON or XML format.",
  "operationId": "getOrders",
  "parameters": [
    {
      "name": "format",
      "in": "query",
      "description": "The response format (json or xml)",
      "required": false,
      "schema": {
        "type": "string",
        "enum": [
          "json",
          "xml"
        ]
      }
    }
  ],
  "responses": {
    ...
  }
}

๐Ÿ“– Documentation (Swagger docs and RapiDoc)

Mount the documentation views in your route file.

# config/routes.rb

Rails.application.routes.draw do
  # Rest of the routes...
  mount Apicraft::Web::App, at: "/apicraft"
end

You can browse API Documentation at

  • /apicraft/swaggerdoc
  • /apicraft/rapidoc

Enable authentication for the /apicraft namespace.

# config/application.rb
module App
  class Application < Rails::Application
    # Rest of the configuration...
    Apicraft::Web::App.use do |user, password|
      [user, password] == ["admin", "password"]
    end
  end
end
RapiDoc SwaggerDoc

๐Ÿ”ง Configuration

List of available configurations.

Apicraft.configure do |config|
  config.contracts_path = Rails.root.join("app/contracts")

  # Enables or disables the mocking features
  # Defaults to true
  config.mocks = true

  # Enables or disables the introspection features
  # Defaults to true
  config.introspection = true

  # allows you to enforce stricter validation of $ref
  # references in your OpenAPI specifications.
  # When this option is enabled, the parser will raise
  # an error if any $ref references in your OpenAPI
  # document are invalid, ensuring that all references
  # are correctly defined and resolved.
  # Defaults to true
  config.strict_reference_validation = true

  # When simulating delay using the mocks, the max
  # delay in seconds that can be simulated
  config.max_allowed_delay = 30

  config.headers = {
    # The name of the header used to control
    # the response code of the mock
    # Defaults to Apicraft-Response-Code
    response_code: "Apicraft-Response-Code",

    # The name of the header to introspect the API.
    # Defaults to Apicraft-Introspect
    introspect: "Apicraft-Introspect",

    # The name of the header to mock the API.
    # Defaults to Apicraft-Mock
    mock: "Apicraft-Mock",

    # Delay simulation header name
    delay: "Apicraft-Delay"
  }

  config.request_validation = {
    enabled: true,

    # Return the http code for validation errors, defaults to 400
    http_code: 400,

    # Return a custom response body, defaults to `{ message: "..." }`
    response_body: proc do |ex|
      {
        message: ex.message
      }
    end
  }
end

Apicraft::Web::App.use do |user, password|
  [user, password] == ["admin", "password"]
end

๐Ÿค Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/apicraft-dev/apicraft-rails. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the code of conduct.

๐Ÿ“ License

The gem is available as open source under the terms of the MIT License.

๐Ÿ“˜ Code of Conduct

Everyone interacting in the Apicraft project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.