8

I used Bravado to create a Python client to a REST API for the petstore.

I need to do the same to get a dynamic Ruby client to the REST API.

  • I saw a list of tools in the OS integrations Swagger page but most of them seems to be to automate tests using Swagger or to create a Swagger/openapi API, not to create Client that consume a Swagger API.

  • Svelte, is a "Dynamic Ruby API Client from Swagger JSON Spec" in the above list. It could be a good candidate, and looks similar to the Bravado Python lib I already use, but:

    • it seems that Request parameter validation is only done for URL-based parameters, so it will not provide requests, and the responses validation against the Swagger 2.0 Spec like here.
    • Svelte returns a Faraday::Request not a model instance.
  • Ruby gem OpenAPI is officially a Ruby wrapper, which is what we are looking for, but there is not yet any documentation Cf. the main README: "In Active dev. documentation is coming"
  • Excon (thank you @kevin-burnett to point at it) does not provide an automated wrapper to the API describe by Swagger, it's an HTTP client, corresponding to Python's Requests, so a lib to manually consume the API.

Here is code in Python that is the kind of feature we are looking for in Ruby:

To get simple dict answer (without using models):

from bravado.client import SwaggerClient
from bravado.fido_client import FidoClient

client = SwaggerClient.from_url(
    'http://petstore.swagger.io/v2/swagger.json',
    config={'use_models': False}
)

result = client.pet.getPetById(petId=42).result(timeout=4)

provide:

>>> result
{'category': {'id': 42, 'name': 'string'},
 'id': 42,
 'name': 'doggie',
 'photoUrls': ['string', 'string2'],
 'status': 'available',
 'tags': [{'id': 42, 'name': 'string'}]}

And even better, by default using the model:

> from bravado.client import SwaggerClient

> client = SwaggerClient.from_url("http://petstore.swagger.io/v2/swagger.json")
> pet = client.pet.getPetById(petId=42).result()
> print(pet)
Pet(category=Category(id=42, name='string'), id=42,
    name='doggie', photoUrls=['string', 'string2'],
    status='available',
    tags=[Tag(id=42, name='string')])
>
user3313834
  • 7,327
  • 12
  • 56
  • 99
  • Please read "[ask]" including the linked pages, "[mcve]" and "[How much research effort is expected of Stack Overflow users?](http://meta.stackoverflow.com/questions/261592)". We'd like to see evidence of your effort. What did you try? Did you search and not find anything? Did you find stuff but it didn't help? Did you try writing code? If not, why? If so, what is the smallest code example that shows what you tried and why didn't it work? Without that it looks like you didn't try and want us to write it for you. – the Tin Man Apr 29 '17 at 21:23
  • Sorry I just updated my question to expose the context and investigations – user3313834 Apr 30 '17 at 11:06
  • 1
    I'd like to help, but I don't think you've included enough about what you want to be able to do. Showing us what you've done in Python isn't sufficient. – Mark Thomas May 02 '17 at 11:45
  • It appears that you're looking for a dual API, with options to return a data structure, and another to return an object? Can you provide some more detail on what you'd like to accomplish? – Mark Thomas May 02 '17 at 11:52
  • 1
    I'm still trying to wrap my head around the problem. I get that you're not trying to create a simple API client for the PetStore, you're trying to do something more dynamic. For those of us not familiar with the Swagger API, can you tell us what `swagger.json` represents? And specifically what you want to do with it? – Mark Thomas May 02 '17 at 12:10
  • swagger.json is a definition format to describe RESTful APIs ; it map all the resources and operations. It represent the specification of the REST api exposed, (it's like a sitemap for the API you intent to use). There is enough information in it to automatically generate a Ruby client that "map"/proxify calls to the API to hight level Ruby objects. – user3313834 May 02 '17 at 12:37
  • Thanks, that helps with some of the background. Now, what is your specific question? – Mark Thomas May 02 '17 at 13:52
  • My specific question is to get a "Dynamic Ruby API Client from Swagger JSON Spec" by dynamic I mean that "Ruby wrapper" that will provide objects that we will not have to write. – user3313834 May 02 '17 at 14:22
  • 1
    Sorry, but that's not specific at all. That's a general description of your end state. I'm in agreement with @theTinMan that this is like a "write it for me" type "question." – Mark Thomas May 02 '17 at 20:00
  • I think this question should be closed, but in the spirit of being helpful, I did a little research and what you're asking has already been done in many languages including Ruby: http://swagger.io/swagger-codegen/ – Mark Thomas May 02 '17 at 20:07
  • "My specific question is to get a "Dynamic Ruby API Client from Swagger JSON Spec" by dynamic I mean that "Ruby wrapper" that will provide objects that we will not have to write." isn't a question, and not even a complete sentence. It's really important to write a clear question, and that's what we're not seeing. And, again, it looks like you want us to find, or write, something for you. Instead, you need to search, to find candidates, to try writing code against one, and then, if you have a problem with the code, ask a specific question about that problem. Currently the question is premature. – the Tin Man May 02 '17 at 20:57
  • Providing Python code doesn't really help, except to explain what you want us to find/recommend, or write, in Ruby. If you'd written Ruby code and asked a specific question about it then the question could be on-topic, but currently it's broad, ill-defined, and smells of asking for recommendations. Understand that we're trying to help you create a good question that fits the needs of the site and will help others in the future, not just answer your particular need now. – the Tin Man May 02 '17 at 21:01

2 Answers2

2

You can use ruby-swagger to convert swagger.json to API client

You can look at this command:

 rake swagger:generate_client:ruby

Also you can look at swagger-codegen

slal
  • 2,657
  • 18
  • 29
  • the question is not about creating an api but consuming it in a ruby client, yes swagger-codegen is probably the best non-dynamic (java compilation) solution – user3313834 May 16 '17 at 08:10
  • Is this the best solution? I consumed an sdk created by azure AutoRest but it is breaking – satchel Jun 04 '21 at 19:27
0

There are lots of others, but excon is pretty sweet.

Include it in your Gemfile:

gem 'excon'

Then, to to do a GET request, for example:

require 'json'
require 'excon'
excon_result = Excon.get('http://petstore.swagger.io/v2/pet/findByStatus?status=pending')
response_body_as_string = excon_result.body
pets = JSON.parse(response_body_as_string)
pets.first['name'] # "hello kity with form updated" (sic)

Excon has lots of neat features such as the expects option that allows you to specify a list of http status codes that you expect. If the response is outside of the expectation, it will raise automatically.

burnettk
  • 13,557
  • 4
  • 51
  • 52
  • Please keep these in mind when answering poorly asked questions: https://meta.stackoverflow.com/questions/256328/vote-to-close-unclear-questions-immediately-after-commenting and https://meta.stackoverflow.com/questions/260263/how-long-should-we-wait-for-a-poster-to-clarify-a-question-before-closing – the Tin Man Apr 29 '17 at 21:24
  • thanks for these pointers, [the Tin Man](http://stackoverflow.com/users/128421/the-tin-man). i'm continually impressed at the amount of thought that goes into making this site work well. – burnettk Apr 30 '17 at 02:17
  • I've updated my question taking excon into account, thanks – user3313834 Apr 30 '17 at 11:08