model_driven_api 3.1.10 → 3.1.11

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: 0afb3dc1dca5b7277c7ea2bfd601669765d5227fe68ede17fa6fbfc3de19d36f
4
- data.tar.gz: 02c3ece69e6237b42f8f04de6660469d528c81a84cf392a34a743360b765d832
3
+ metadata.gz: bbaf42c9a62f9ebdc9cdf60633aeeb47ad39b11e9ebb9d20a94af73fea6c7213
4
+ data.tar.gz: c56851d1ae81777a20cc1d7ea26c0a31fb2f349933df72e41f303b8194cc8da6
5
5
  SHA512:
6
- metadata.gz: 92c3d537101cb23123ce34564eaac4fe1d767770628dddcd1cc94487253bb82c880e07721a78c2be3dc571c370020b12e13ab30e9981d035c7766634dccdeb7b
7
- data.tar.gz: 69385bf1c20fe26e8168be63da529edb847002984084e133e431aef6b07815bb88edf1f42ed43d65dc0ef5194a28ede011c29f05aca3de0176dd11a119da3a8a
6
+ metadata.gz: 67ff210a1024a027db62fdaad0091b52229b36d61753ee95c128930a3e4ea8bd127bc1bf8e61209a7aac9938b0c32fd768cdd8b72548adf7f8cc1336b41c95e6
7
+ data.tar.gz: fc5a82329178979b349055efb02840708ee1d2df4a3ea37d19f9b317403a5d583a584c25f712e3a72c83d438d344d46fbcfb8762bfa573d40909f991e8716fc6
@@ -515,49 +515,17 @@ class Api::V2::InfoController < Api::V2::ApplicationController
515
515
  }
516
516
  }
517
517
  # Non CRUD or Search, but custom, usually bulk operations endpoints
518
- custom_actions = d.methods(false).select do |m| m.to_s.starts_with?("custom_action_") end
519
- # Add also custom actions created using th enew Endpoints Interface
520
- custom_actions += "Endpoints::#{d.model_name.name}".constantize.methods(false) rescue []
521
- custom_actions.each do |action|
522
- custom_action_name = action.to_s.gsub("custom_action_", "")
523
- pivot["/#{model}/custom_action/#{custom_action_name}"] = {
524
- "get": {
525
- "summary": "Custom Action #{custom_action_name.titleize}",
526
- "description": "This is just an example of a custom action, they can accept a wide range of payloads and response with a wide range of responses, also all verbs are valid. Please refer to the documentation for more information.",
527
- "tags": [model.classify],
528
- "security": [
529
- "bearerAuth": []
530
- ],
531
- "responses": {
532
- "200": {
533
- "description": "Custom Action",
534
- "content": {
535
- "application/json": {
536
- "schema": {
537
- "type": "object",
538
- "properties": {
539
- "id": {
540
- "type": "integer"
541
- },
542
- "created_at": {
543
- "type": "string",
544
- "format": "date-time"
545
- },
546
- "updated_at": {
547
- "type": "string",
548
- "format": "date-time"
549
- }
550
- }
551
- }
552
- }
553
- }
554
- },
555
- "404": {
556
- "description": "No #{model} found"
557
- }
558
- }
559
- }
560
- }
518
+ new_custom_actions = ("Endpoints::#{d.model_name.name}".constantize.instance_methods(false) rescue [])
519
+ # Rails.logger.debug "New Custom Actions (#{d.model_name.name}): #{new_custom_actions}"
520
+ new_custom_actions.each do |action|
521
+ openapi_definition = "Endpoints::#{d.model_name.name}".constantize.definitions[action.to_sym] rescue false
522
+
523
+ # Add the tag to the openapi definition
524
+ openapi_definition.each do |k, v|
525
+ v[:tags] = [ d.model_name.name ]
526
+ end
527
+
528
+ pivot["/#{model}/custom_action/#{action}"] = openapi_definition if openapi_definition
561
529
  end
562
530
  pivot["/#{model}/search"] = {
563
531
  # Complex queries are made using ranskac search via a post endpoint
@@ -1,56 +1,78 @@
1
1
  class Endpoints::TestApi < NonCrudEndpoints
2
- def test(params)
3
- # Define an explain var to be used to validate and document the action behavior when using ?explain=true in query string
4
- explain = {
5
- verbs: ["GET", "POST"],
6
- body: {
7
- messages: {
8
- type: :array,
9
- optional: true,
10
- items: {
11
- type: :string,
12
- optional: false
2
+ self.desc :test, {
3
+ # Define the action name using openapi swagger format
4
+ get: {
5
+ summary: "Test API Custom Action",
6
+ description: "This is a test API custom action",
7
+ operationId: "test",
8
+ tags: ["Test"],
9
+ parameters: [
10
+ {
11
+ name: "explain",
12
+ in: "query",
13
+ description: "Explain the action by returning this openapi schema",
14
+ required: true,
15
+ schema: {
16
+ type: "boolean"
13
17
  }
14
- },
15
- is_connected: {
16
- type: :boolean,
17
- optional: false
18
- },
19
- user: {
20
- type: :object,
21
- optional: true,
22
- properties: {
23
- name: {
24
- type: :string,
25
- optional: false
26
- },
27
- age: {
28
- type: :integer,
29
- optional: true
18
+ }
19
+ ],
20
+ responses: {
21
+ 200 => {
22
+ description: "The openAPI json schema for this action",
23
+ content: {
24
+ "application/json": {
25
+ schema: {
26
+ type: "object",
27
+ additionalProperties: true
28
+ }
30
29
  }
31
30
  }
31
+ },
32
+ 501 => {
33
+ error: :string,
32
34
  }
33
- },
34
- query: {
35
- explain: {
36
- type: :boolean,
37
- optional: true
35
+ }
36
+ },
37
+ post: {
38
+ summary: "Test API Custom Action",
39
+ description: "This is a test API custom action",
40
+ operationId: "test",
41
+ tags: ["Test"],
42
+ requestBody: {
43
+ required: true,
44
+ content: {
45
+ "application/json": {}
38
46
  }
39
47
  },
40
48
  responses: {
41
49
  200 => {
42
- message: :string,
43
- params: {},
50
+ description: "The openAPI json schema for this action",
51
+ # This will return the object with a message string and a params object
52
+ content: {
53
+ "application/json": {
54
+ schema: {
55
+ type: "object",
56
+ properties: {
57
+ message: {
58
+ type: "string"
59
+ },
60
+ params: {
61
+ type: "object",
62
+ additionalProperties: true
63
+ }
64
+ }
65
+ }
66
+ }
67
+ }
44
68
  },
45
69
  501 => {
46
70
  error: :string,
47
- },
48
- },
71
+ }
72
+ }
49
73
  }
50
- return explain, 200 if params[:explain].to_s == "true" && !explain.blank?
51
-
52
-
74
+ }
75
+ def test(params)
53
76
  return { message: "Hello World From Test API Custom Action called test", params: params }, 200
54
77
  end
55
78
  end
56
- # end
@@ -1,3 +1,3 @@
1
1
  module ModelDrivenApi
2
- VERSION = "3.1.10".freeze
2
+ VERSION = "3.1.11".freeze
3
3
  end
@@ -1,37 +1,45 @@
1
1
  class NonCrudEndpoints
2
2
  attr_accessor :result
3
+ cattr_accessor :definitions
4
+ self.definitions = {}
3
5
  # Add a validation method which will be inherited by all the instances, and automatically run before any method call
4
6
  def initialize(m, params)
5
7
  # Check if self hase the m method, if not, raise a NoMethodError
6
- raise NoMethodError, "The method #{m} does not exist in #{self.class}" unless self.respond_to? m
7
- definition = self.send(m, { explain: true }) rescue []
8
- validate_request(definition.first.presence || {}, params)
8
+ raise NoMethodError, "The method #{m} does not exist in #{self.class.name}" unless self.respond_to? m
9
+ @definition = self.definitions[m.to_sym].with_indifferent_access
10
+
11
+ # self.send(m, { explain: true }) rescue []
12
+ validate_request(params)
9
13
  @result = self.send(m, params)
10
14
  end
11
15
 
12
- def validate_request(definition, params)
16
+ def validate_request(params)
13
17
  # If there is no definition, return
14
- return if definition.blank?
18
+ return if @definition.blank?
15
19
  # puts "Called Class is: #{self.class}"
16
20
  # puts "Which is son of: #{self.class.superclass}"
17
- body_mandatory_keys = definition[:body].select { |k, v| v[:optional] == false }.keys
18
- query_mandatory_keys = definition[:query].select { |k, v| v[:optional] == false }.keys
19
- # Raise a ValidationError if the request does not match the definition
20
- raise EndpointValidationError, "The verb \"#{params[:request_verb].presence || "No Verb Provided"}\" is not present in #{definition[:verbs].join(", ")}." if definition[:verbs].exclude? params[:request_verb]
21
- # Raise an exception if the verb is put or post and the body keys in definition are not all present as params keys, both params and definition[:body] can have nested objects
22
- raise EndpointValidationError, "The request body does not match the definition: in #{params[:request_verb]} requests all of the params must be present in definition. The body definition is #{definition[:body]}." if params[:request_verb] != "GET" && (body_mandatory_keys & params.keys) != body_mandatory_keys
23
- # Raise an exception if the verb is put or post and the body keys in definition are not all present as params keys, both params and definition[:body] can have nested objects
24
- raise EndpointValidationError, "The request query does not match the definition. The query definition is: #{definition[:query]}." if (query_mandatory_keys & params.keys) != query_mandatory_keys
25
- # Rais if the type of the param is not the same as the definition
26
- definition[:body].each do |k, v|
27
- next if params[k].nil?
28
- computed_type = get_type(params[k])
29
- raise EndpointValidationError, "The type of the param #{k} is not the same as the definition. The definition is #{v[:type]} and the param is #{computed_type}." if v[:type] != computed_type
30
- end
21
+ # body_mandatory_keys = definition[:body].select { |k, v| v[:optional] == false }.keys
22
+ # query_mandatory_keys = definition[:query].select { |k, v| v[:optional] == false }.keys
23
+ # # Raise a ValidationError if the request does not match the definition
24
+ # raise EndpointValidationError, "The verb \"#{params[:request_verb].presence || "No Verb Provided"}\" is not present in #{definition.keys.join(", ")}." if definition.keys.exclude? params[:request_verb]
25
+ # # Raise an exception if the verb is put or post and the body keys in definition are not all present as params keys, both params and definition[:body] can have nested objects
26
+ # raise EndpointValidationError, "The request body does not match the definition: in #{params[:request_verb]} requests all of the params must be present in definition. The body definition is #{definition[:body]}." if params[:request_verb] != "GET" && (body_mandatory_keys & params.keys) != body_mandatory_keys
27
+ # # Raise an exception if the verb is put or post and the body keys in definition are not all present as params keys, both params and definition[:body] can have nested objects
28
+ # raise EndpointValidationError, "The request query does not match the definition. The query definition is: #{definition[:query]}." if (query_mandatory_keys & params.keys) != query_mandatory_keys
29
+ # # Rais if the type of the param is not the same as the definition
30
+ # definition[:body].each do |k, v|
31
+ # next if params[k].nil?
32
+ # computed_type = get_type(params[k])
33
+ # raise EndpointValidationError, "The type of the param #{k} is not the same as the definition. The definition is #{v[:type]} and the param is #{computed_type}." if v[:type] != computed_type
34
+ # end
31
35
  end
32
36
 
33
37
  private
34
38
 
39
+ def self.desc(key, definition)
40
+ self.definitions[key] = definition
41
+ end
42
+
35
43
  def get_type(type)
36
44
  case type
37
45
  when String
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: model_driven_api
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.10
4
+ version: 3.1.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gabriele Tassoni
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-03-18 00:00:00.000000000 Z
11
+ date: 2024-03-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thecore_backend_commons