apicraft-rails 0.5.0.beta1 โ†’ 0.5.1.beta1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 847b284dc12a51e2364740eef912f4238c771a7e9d143fa7ea63090afca69e03
4
- data.tar.gz: 1a2c2c667280415035ca7af8a95de9dbadc2859ee932a65c4890b30f37208821
3
+ metadata.gz: 03c78edc81f87417dfdd7411be50609da4d39bb0827775ea16b609cce641a7bd
4
+ data.tar.gz: 652eb5761da35bc28f8a779015c74ef0b971d94231250aa02edcd3c3ff1cc7b3
5
5
  SHA512:
6
- metadata.gz: 588307957dd26f89f9f661ab36f55ea33d47fd601e4f563481e32a29a526734c8daa8e2c51bd2741ace545a52079549587f7cc720f9c1f84f7187533cf4dd294
7
- data.tar.gz: 4a65d260b4f9124733cb1aeb1d069598f0f87ad6e4a6322c0bfa2ba842fdbcca2de626e23fb6dfbcae0340eb8ddb51a4400867e544a278c4fa2dd12c237bfe4b
6
+ metadata.gz: fe96cef636e07bc57e26ff11401e315ab457783cf254f33de98ec233a8f2c4b72be7c4b4f593f023deb615b17ce5166f8309fabc6a298139913d58e478363489
7
+ data.tar.gz: f23638693ebe922a7de1b98bfef20f7cad9777704c21603489ffe6677afc33ec9020173a2cfdb76dd59c52e7246a42dbb55fcd2443f9ff7fa4946a6764c84dd6
data/README.md CHANGED
@@ -1,10 +1,33 @@
1
1
  # APICraft Rails (Beta)
2
2
  [![Build](https://github.com/apicraft-dev/apicraft-rails/actions/workflows/build.yml/badge.svg)](https://github.com/apicraft-dev/apicraft-rails/actions/workflows/build.yml)
3
+ [![Gem Version](https://badge.fury.io/rb/apicraft-rails.svg)](https://badge.fury.io/rb/apicraft-rails)
3
4
 
4
5
  ๐Ÿš€ 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.
5
6
 
7
+ 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**](#-api-design-first-philosophy), ensuring that contracts remain independent from implementation.
8
+
9
+ 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.
10
+
11
+ It avoids the pitfalls of the code-first methodology, where contracts are auto-generated, often leading to inconsistency and misalignment.
12
+
6
13
  ![APICraft Rails Logo](assets/apicraft_rails.png)
7
14
 
15
+ - [APICraft Rails (Beta)](#apicraft-rails-beta)
16
+ - [โœจ Features](#-features)
17
+ - [๐Ÿ”œ Upcoming Features](#-upcoming-features)
18
+ - [๐Ÿช„ Works Like Magic](#-works-like-magic)
19
+ - [๐Ÿ•Š API Design First Philosophy](#-api-design-first-philosophy)
20
+ - [๐Ÿ— Installation](#-installation)
21
+ - [โš™๏ธ Usage](#๏ธ-usage)
22
+ - [๐ŸŽญ API Mocking](#-api-mocking)
23
+ - [๐ŸŽฎ API Mocking (Behaviours)](#-api-mocking-behaviours)
24
+ - [๐Ÿง API Introspection](#-api-introspection)
25
+ - [๐Ÿ“– API Documentation (Swagger docs and RapiDoc)](#-api-documentation-swagger-docs-and-rapidoc)
26
+ - [๐Ÿ”ง Configuration](#-configuration)
27
+ - [๐Ÿค Contributing](#-contributing)
28
+ - [๐Ÿ“ License](#-license)
29
+ - [๐Ÿ“˜ Code of Conduct](#-code-of-conduct)
30
+
8
31
  ## โœจ Features
9
32
  - ๐Ÿง‘โ€๐Ÿ’ป๏ธ **Dynamic Mock Data Generation** - Detects the specifications and instantly mounts working routes with mock responses. No extra configuration required.
10
33
 
@@ -12,11 +35,13 @@
12
35
 
13
36
  - ๐Ÿ” **API Introspections** - Introspect API schemas without needing to dig into the docs everytime.
14
37
 
15
- - ๐Ÿ“บ **Documentation Out of the Box** - Documentation using `SwaggerDoc` and `Redoc` both.
38
+ - ๐Ÿ“บ **Documentation Out of the Box** - Documentation using `SwaggerDoc` and `RapiDoc` both.
16
39
 
17
40
  - ๐Ÿ—‚ **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
18
41
 
19
- - ๐Ÿ”œ **Request Validations** - Automatic request validations (coming soon)
42
+ ## ๐Ÿ”œ Upcoming Features
43
+ - ๐Ÿ’ข **Request Validations** - Automatic request validations.
44
+ - ๐Ÿ’Ž **Clean & Custom Ruby DSL** - Support for a Ruby DSL alongwith the current `.json` and `.yaml` formats.
20
45
 
21
46
 
22
47
  ## ๐Ÿช„ Works Like Magic
@@ -42,12 +67,12 @@ The API Design First philosophy is at the heart of APICraft Rails, and itโ€™s a
42
67
  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.
43
68
 
44
69
 
45
- ## Installation
70
+ ## ๐Ÿ— Installation
46
71
 
47
72
  Add this line to your application's Gemfile:
48
73
 
49
74
  ```ruby
50
- gem 'apicraft-rails', '~> 0.5.0.beta1'
75
+ gem 'apicraft-rails', '~> 0.5.1.beta1'
51
76
  ```
52
77
 
53
78
  And then execute:
@@ -76,7 +101,7 @@ end
76
101
 
77
102
  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.
78
103
 
79
- ## Usage
104
+ ## โš™๏ธ Usage
80
105
 
81
106
  Add your specification files to the `app/contracts` directory in your Rails project. You can also configure this directory to be something else.
82
107
  ```
@@ -92,7 +117,7 @@ my_rails_app/
92
117
  โ”‚ โ”‚ โ”œโ”€โ”€ user.rb
93
118
  โ”‚ โ”‚ โ””โ”€โ”€ order.rb
94
119
  ```
95
- ### ๐Ÿฅท Working with Mock APIs
120
+ ### ๐ŸŽญ API Mocking
96
121
  **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.
97
122
 
98
123
  `https://yoursite.com/api/orders`
@@ -116,6 +141,7 @@ headers: {
116
141
  ]
117
142
  ```
118
143
 
144
+ ### ๐ŸŽฎ API Mocking (Behaviours)
119
145
  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.
120
146
 
121
147
  `https://yoursite.com/api/orders`
@@ -132,7 +158,7 @@ headers: {
132
158
  }
133
159
  ```
134
160
 
135
- ### ๐Ÿ‘€ API Introspection
161
+ ### ๐Ÿง API Introspection
136
162
  All APIs are can be introspected. You can do so by passing the `Apicraft-Introspection` header.
137
163
 
138
164
  ```
@@ -167,7 +193,7 @@ Example: `https://yoursite.com/api/orders`
167
193
  }
168
194
  }
169
195
  ```
170
- ### ๐Ÿ‘€ API Documentation
196
+ ### ๐Ÿ“– API Documentation (Swagger docs and RapiDoc)
171
197
 
172
198
  Mount the documentation views in your route file.
173
199
 
@@ -182,7 +208,7 @@ end
182
208
 
183
209
  You can browse API Documentation at
184
210
  - `/apicraft/swaggerdoc`
185
- - `/apicraft/redoc`
211
+ - `/apicraft/rapidoc`
186
212
 
187
213
  Enable authentication for the `/apicraft` namespace.
188
214
 
@@ -198,7 +224,7 @@ module App
198
224
  end
199
225
  ```
200
226
 
201
- ## Configuration
227
+ ## ๐Ÿ”ง Configuration
202
228
 
203
229
  List of available configurations.
204
230
 
@@ -244,14 +270,14 @@ Apicraft::Web::App.use do |user, password|
244
270
  end
245
271
  ```
246
272
 
247
- ## Contributing
273
+ ## ๐Ÿค Contributing
248
274
 
249
275
  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](https://github.com/apicraft-dev/apicraft-rails/blob/main/CODE_OF_CONDUCT.md).
250
276
 
251
- ## License
277
+ ## ๐Ÿ“ License
252
278
 
253
279
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
254
280
 
255
- ## Code of Conduct
281
+ ## ๐Ÿ“˜ Code of Conduct
256
282
 
257
283
  Everyone interacting in the Apicraft project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/apicraft/blob/main/CODE_OF_CONDUCT.md).
@@ -2,5 +2,5 @@
2
2
 
3
3
  # Current version of Apicraft.
4
4
  module Apicraft
5
- VERSION = "0.5.0.beta1"
5
+ VERSION = "0.5.1.beta1"
6
6
  end
@@ -5,16 +5,11 @@ module Apicraft
5
5
  # Web actions to be handled from
6
6
  # the rack app.
7
7
  module Actions
8
- def self.index(view_path)
9
- [
10
- File.read(view_path),
11
- "text/html"
12
- ]
13
- end
14
-
15
- def self.swaggerdoc(view_path)
8
+ def self.render_erb(view_path)
16
9
  @vars = {
17
- urls: Router.contract_urls
10
+ urls: Router.contract_urls,
11
+ namespace: Router.namespace,
12
+ version: Apicraft::VERSION
18
13
  }
19
14
 
20
15
  [
@@ -25,16 +20,10 @@ module Apicraft
25
20
  ]
26
21
  end
27
22
 
28
- def self.redoc(view_path)
29
- @vars = {
30
- urls: Router.contract_urls
31
- }
32
-
23
+ def self.images(view_path)
33
24
  [
34
- ERB.new(
35
- File.read(view_path)
36
- ).result(binding),
37
- "text/html"
25
+ File.read(view_path),
26
+ mime_type(view_path)
38
27
  ]
39
28
  end
40
29
 
@@ -45,15 +34,9 @@ module Apicraft
45
34
  ]
46
35
  end
47
36
 
48
- def self.introspect(method, view_path)
49
- [
50
- Apicraft::Openapi::Contract.find_by_operation(
51
- method, view_path
52
- )&.operation(
53
- method, view_path
54
- )&.raw_schema&.to_json,
55
- "application/json"
56
- ]
37
+ def self.mime_type(view_path)
38
+ ext = File.extname(view_path)
39
+ Rack::Mime.mime_type(ext)
57
40
  end
58
41
  end
59
42
  end
@@ -13,10 +13,10 @@ module Apicraft
13
13
  Router.namespace = env["SCRIPT_NAME"]
14
14
  path = uri.split(
15
15
  Router.namespace
16
- )[-1]
16
+ )[-1] || "/"
17
17
 
18
18
  content, content_type = Router.load_response!(
19
- method, path || "/"
19
+ method, path
20
20
  )
21
21
 
22
22
  raise Errors::RouteNotFound if content.nil?
@@ -7,20 +7,33 @@ module Apicraft
7
7
  WEB_ROOT = File.expand_path(
8
8
  "#{File.dirname(__FILE__)}/../../../web"
9
9
  )
10
+ IMAGES_DIR = "#{WEB_ROOT}/assets/images"
10
11
 
11
12
  def self.routes
12
13
  @routes ||= {
13
14
  "/": {
14
- action: :index,
15
- view_path: "#{WEB_ROOT}/views/index.html"
15
+ action: :render_erb,
16
+ view_path: "#{WEB_ROOT}/views/index.erb"
16
17
  },
17
18
  "/swaggerdoc": {
18
- action: :swaggerdoc,
19
+ action: :render_erb,
19
20
  view_path: "#{WEB_ROOT}/views/swaggerdoc.erb"
20
21
  },
21
22
  "/redoc": {
22
- action: :redoc,
23
+ action: :render_erb,
23
24
  view_path: "#{WEB_ROOT}/views/redoc.erb"
25
+ },
26
+ "/rapidoc": {
27
+ action: :render_erb,
28
+ view_path: "#{WEB_ROOT}/views/rapidoc.erb"
29
+ },
30
+ "/assets/images/thumb.png": {
31
+ action: :images,
32
+ view_path: "#{IMAGES_DIR}/apicraft_thumb.png"
33
+ },
34
+ "/assets/images/logo.png": {
35
+ action: :images,
36
+ view_path: "#{IMAGES_DIR}/apicraft.png"
24
37
  }
25
38
  }.with_indifferent_access
26
39
  end
@@ -32,9 +45,7 @@ module Apicraft
32
45
  }
33
46
  end
34
47
 
35
- def self.load_response!(method, path)
36
- return Actions.introspect(method, path) unless routes[path].present?
37
-
48
+ def self.load_response!(_method, path)
38
49
  Actions.send(
39
50
  routes[path][:action],
40
51
  routes[path][:view_path]
Binary file
@@ -0,0 +1,83 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>APICraft</title>
5
+ <meta charset="utf-8"/>
6
+ <meta name="viewport" content="width=device-width, initial-scale=1">
7
+ <link href="https://fonts.googleapis.com/css?family=Montserrat:300,400,700|Roboto:300,400,700" rel="stylesheet">
8
+ <style>
9
+ body {
10
+ margin: 0;
11
+ padding-top: 40px;
12
+ font-family: 'Montserrat', 'Roboto', sans-serif;
13
+ background-color: #121212;
14
+ position: relative;
15
+ }
16
+ #container {
17
+ margin-top: 60px;
18
+ text-align: center;
19
+ max-width: 550px;
20
+ margin-left: auto;
21
+ margin-right: auto;
22
+ color: white;
23
+ }
24
+ .muted {
25
+ opacity: 0.5;
26
+ }
27
+ .primary-btn {
28
+ background-color: #4C2A85;
29
+ color: white;
30
+ padding: 10px 20px;
31
+ text-decoration: none;
32
+ border-radius: 5px;
33
+ font-size: 16px;
34
+ display: inline-block;
35
+ cursor: pointer;
36
+ transition: background-color 0.3s ease;
37
+ }
38
+
39
+ .primary-btn:hover {
40
+ background-color: #3A2064;
41
+ }
42
+
43
+ .github-btn {
44
+ background-color: white;
45
+ color: #4C2A85;
46
+ padding: 5px 10px;
47
+ text-decoration: none;
48
+ border-radius: 5px;
49
+ font-size: 12px;
50
+ display: inline-block;
51
+ border: 2px solid #4C2A85;
52
+ cursor: pointer;
53
+ transition: background-color 0.3s ease, color 0.3s ease, box-shadow 0.3s ease;
54
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
55
+ }
56
+
57
+ .github-btn:hover {
58
+ box-shadow: 0 6px 8px rgba(0, 0, 0, 0.15);
59
+ }
60
+ </style>
61
+ </head>
62
+ <body>
63
+ <div id="container">
64
+ <img src="<%= @vars[:namespace] %>/assets/images/logo.png" height="120" width="120"/>
65
+ <p>Welcome to <strong>API</strong>Craft.<p>
66
+ <p class="muted">An opinionated framework for an API Design First approach to development.</p>
67
+ <div>
68
+ <a class="primary-btn" href="<%= @vars[:namespace] %>/rapidoc">RapiDoc</a>
69
+ <a class="primary-btn" href="<%= @vars[:namespace] %>/swaggerdoc">Swagger</a>
70
+ </div>
71
+ <br/>
72
+ <div>
73
+ <a href="https://github.com/apicraft-dev/apicraft-rails" class="github-btn" target="_blank">
74
+ โญ Star us on GitHub
75
+ </a>
76
+ </div>
77
+ <br/>
78
+ <div>
79
+ <code class="muted">v<%= @vars[:version] %></code>
80
+ </div>
81
+ </div>
82
+ </body>
83
+ </html>
@@ -0,0 +1,102 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>APICraft - Rapidoc</title>
5
+ <meta charset="utf-8"/>
6
+ <meta name="viewport" content="width=device-width, initial-scale=1">
7
+ <link href="https://fonts.googleapis.com/css?family=Montserrat:300,400,700|Roboto:300,400,700" rel="stylesheet">
8
+ <style>
9
+ body {
10
+ margin: 0;
11
+ font-family: 'Montserrat', 'Roboto', sans-serif;
12
+ background-color: #121212;
13
+ }
14
+
15
+ .select-label {
16
+ color: white;
17
+ font-weight: 400;
18
+ margin-right: 10px;
19
+ }
20
+
21
+ #api_select {
22
+ padding: 16px 16px;
23
+ color: white;
24
+ background-color: black;
25
+ border: none;
26
+ border-bottom: 1px solid #333;
27
+ border-radius: 0px;
28
+ cursor: pointer;
29
+ outline: none !important;
30
+ width: 100%;
31
+ display: none;
32
+ }
33
+
34
+ rapi-doc {
35
+ flex-grow: 1;
36
+ height: calc(100vh - 0px); /* Adjust for nav height */
37
+ width: 100%;
38
+ display: none;
39
+ }
40
+ </style>
41
+ </head>
42
+ <body>
43
+ <rapi-doc
44
+ theme="dark"
45
+ id="rapidoc_element"
46
+ header-color="#121212"
47
+ primary-color="#4C2A85"
48
+ use-path-in-nav-bar="false"
49
+ bg-color="#111"
50
+ show-header="false"
51
+ >
52
+ <div slot="nav-logo">
53
+ <img
54
+ src="assets/images/thumb.png"
55
+ height="60px"
56
+ width="60px"
57
+ />
58
+ <span style="top: -23px; position: relative;"><strong>API</strong>Craft</span>
59
+ </div>
60
+ <select id="api_select">
61
+ </select>
62
+ </rapi-doc>
63
+ <script type="module" src="https://unpkg.com/rapidoc/dist/rapidoc-min.js"></script>
64
+ <script>
65
+ var $rapiDocElement = document.getElementById('rapidoc_element');
66
+ var $select = document.getElementById('api_select');
67
+
68
+ // List of APIs
69
+ var apis = <%=
70
+ @vars[:urls].map do |u|
71
+ { url: u, name: u.gsub(Apicraft::Web::Router.namespace, "") }
72
+ end.to_json
73
+ %>
74
+
75
+ $rapiDocElement.setAttribute('spec-url', apis[0].url);
76
+ $rapiDocElement.setAttribute('style', "display: block;");
77
+
78
+ // Function to handle API selection change
79
+ function onSelectChange() {
80
+ var url = this.value;
81
+ $rapiDocElement.setAttribute('spec-url', url);
82
+ }
83
+
84
+ // Dynamically building the select dropdown options
85
+ apis.forEach(function(api) {
86
+ var $option = document.createElement('option');
87
+ $option.setAttribute('value', api.url);
88
+ $option.innerText = api.name;
89
+ $select.appendChild($option);
90
+ });
91
+
92
+ // Adding event listener for select dropdown change
93
+ $select.addEventListener('change', onSelectChange);
94
+ $select.setAttribute('style', "display: block;");
95
+ </script>
96
+ <style>
97
+ .header-title {
98
+ display: none !important;
99
+ }
100
+ </style>
101
+ </body>
102
+ </html>
data/web/views/redoc.erb CHANGED
@@ -60,8 +60,32 @@
60
60
  end.to_json
61
61
  %>
62
62
 
63
+ const customTheme = {
64
+ colors: {
65
+ primary: {
66
+ main: '#4CAF50', // Set the primary color to #4CAF50
67
+ },
68
+ text: {
69
+ primary: '#ffffff',
70
+ secondary: '#b0b0b0',
71
+ },
72
+ background: {
73
+ primary: '#1a1a1a', // Set the background color to #1a1a1a
74
+ secondary: '#222222',
75
+ },
76
+ borders: '#4CAF50', // Border color for primary sections
77
+ },
78
+ typography: {
79
+ fontSize: '16px',
80
+ fontFamily: '"Montserrat", "Roboto", sans-serif',
81
+ },
82
+ sidebar: {
83
+ backgroundColor: '#2b2b2b',
84
+ },
85
+ };
86
+
63
87
  // Initially render first API
64
- Redoc.init(apis[0].url);
88
+ Redoc.init(apis[0].url, { theme: null });
65
89
 
66
90
  // Function to handle API selection change
67
91
  function onSelectChange() {
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: apicraft-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0.beta1
4
+ version: 0.5.1.beta1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Abhishek Sarkar
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-09-08 00:00:00.000000000 Z
11
+ date: 2024-09-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -154,7 +154,10 @@ files:
154
154
  - lib/apicraft/web/actions.rb
155
155
  - lib/apicraft/web/app.rb
156
156
  - lib/apicraft/web/router.rb
157
- - web/views/index.html
157
+ - web/assets/images/apicraft.png
158
+ - web/assets/images/apicraft_thumb.png
159
+ - web/views/index.erb
160
+ - web/views/rapidoc.erb
158
161
  - web/views/redoc.erb
159
162
  - web/views/swaggerdoc.erb
160
163
  homepage: https://github.com/apicraft-dev/apicraft-rails
data/web/views/index.html DELETED
@@ -1,15 +0,0 @@
1
- <!DOCTYPE html>
2
- <html>
3
- <head>
4
- <title>APICraft</title>
5
- <meta charset="utf-8"/>
6
- <meta name="viewport" content="width=device-width, initial-scale=1">
7
- <link href="https://fonts.googleapis.com/css?family=Montserrat:300,400,700|Roboto:300,400,700" rel="stylesheet">
8
- <style>
9
- </style>
10
- </head>
11
- <body>
12
- <nav>
13
- </nav>
14
- </body>
15
- </html>