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

Sign up to get free protection for your applications and to get access to all the features.
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>