I'm new to the rails environment and come from a java enterprise web application background. I want to create a few classes that allow you to easily interface with an external application that exposes restful web services. In java I would simply create these as stateless java beans/facade's that return Data Transfer Objects which are nice usable objects instead of ugly xml maps/data. What is the best way to do this in Rails/Ruby? Here's my main questions:
Should the facade classes be static or should you instantiate them before using the service?
Where should the DTO's be placed?
Thanks,
Pierre
UPDATE: We ended up using services as explained in this answer: Moving transactional operations away from the controller
Code that doesn't fit as a model or controller lives in the lib folder. helpers is typically just for view related code that generates HTML or other UI related results.
I'd generally create them as regular classes that are instantiated and have instance methods to access the external rest service - this can make testing them easier. But this is really just a matter of preference (and also depends on how much state/reuse of those objects is required per request - depends on what you're doing exactly).
The "DTOs", would just be plain Ruby classes in this case - maybe even simple Struct instances if they don't have any logic in them. If they are Ruby classes, they'd live in app/models, but they wouldn't extend ActiveRecord::Base (or anything else)
You probably want to take a look at httparty
Here's an example of how you'd consume the twitter api.
# lib/twitter.rb
require 'httparty'
require 'hashie'
class Twitter
include HTTParty
base_uri 'twitter.com'
def timeline
self.class.get("/statuses/public_timeline.xml")["statuses"].map do |status|
Hashie::Mash.new(status)
end
end
end
# client code
client = Twitter.new
message = client.timeline.first
puts message.text
Notice that you don't have to create DTOs. httparty maps xml (take a look at http://dev.twitter.com/doc/get/statuses/public_timeline for the structure in this example) to Hashes and then Hashie::Mash maps them to methods, hence you can just do message.text. It even works recursively so you can do client.timeline.first.user.name.
If you're creating a rails project then I'd place twitter.rb in the lib folder.
If you'd rather use static methods you can do:
require 'httparty'
require 'hashie'
class Twitter
include HTTParty
base_uri 'twitter.com'
def self.timeline
get("/statuses/public_timeline.xml")["statuses"].map do |status|
Hashie::Mash.new(status)
end
end
end
# client code
message = Twitter.timeline.first
puts message.text
Related
I built an android app and have built a corresponding node.js back-end to store data from it. I've got some API end-points created along with methods to save and retrieve data from a MongoDB.
I understand how to make https requests from java/android, but I'm not sure how things should ideally be set-up and structed. Is it best practice to create a new package for api related things? Like for example, a package like:
API Package
Class containing GET requests
Class containing POST requests
These classes might contain methods like:
public static String getItem(int item_id) {
//HTTPS boiler plate
//HTTPS GET request and process data
return result;
Or is it best to create a class to handle and make HTTPS requests and then implement all of the required API methods in a single, separate class?
There are several popular libraries out there that you can check it out like Retrofit or Android Volley. I recommend you not to write the code to make requests to the backend yourself because things like parsing JSON data shouldn't be done manually as everything will be hard to manage when your project grows.
To structure the code, it depends on personal preference. I personally use Retrofit so I keep all network requests in an interface. For example:
interface APIs {
#GET("api/user")
Call<Users> getUsers();
#GET("api/comment")
Call<Comments> getComments();
#GET("api/photos")
Call<Photos> getPhotos();
}
But if you want to learn how things should be set-up and structured nicely, I suggest you read about the Android architecture component and Clean Code architecture where code logics are kept separately and grouped in a manageable way.
I have a web service layer that is written in Java/Jersey, and it serves JSON.
For the front-end of the application, I want to use Rails.
How should I go about building my models?
Should I do something like this?
response = api_client.get_user(123)
User user = User.new(response)
What is the best approach to mapping the JSON to the Ruby object?
What options do I have? Since this is a critical part, I want to know my options, because performance is a factor. This, along with mapping JSON to a Ruby object and going from Ruby object => JSON, is a common occurance in the application.
Would I still be able to make use of validations? Or wouldn't it make sense since I would have validation duplicated on the front-end and the service layer?
Models in Rails do not have to do database operation, they are just normal classes. Normally they are imbued with ActiveRecord magic when you subclass them from ActiveRecord::Base.
You can use a gem such as Virtus that will give you models with attributes. And for validations you can go with Vanguard. If you want something close to ActiveRecord but without the database and are running Rails 3+ you can also include ActiveModel into your model to get attributes and validations as well as have them working in forms. See Yehuda Katz's post for details on that.
In your case it will depend on the data you will consume. If all the datasources have the same basic format for example you could create your own base class to keep all the logic that you want to share across the individual classes (inheritance).
If you have a few different types of data coming in you could create modules to encapsulate behavior for the different types and include the models you need in the appropriate classes (composition).
Generally though you probably want to end up with one class per resource in the remote API that maps 1-to-1 with whatever domain logic you have. You can do this in many different ways, but following the method naming used by ActiveRecord might be a good idea, both since you learn ActiveRecord while building your class structure and it will help other Rails developers later if your API looks and works like ActiveRecords.
Think about it in terms of what you want to be able to do to an object (this is where TDD comes in). You want to be able to fetch a collection Model.all, a specific element Model.find(identifier), push a changed element to the remote service updated_model.save and so on.
What the actual logic on the inside of these methods will have to be will depend on the remote service. But you will probably want each model class to hold a url to it's resource endpoint and you will defiantly want to keep the logic in your models. So instead of:
response = api_client.get_user(123)
User user = User.new(response)
you will do
class User
...
def find id
#api_client.get_user(id)
end
...
end
User.find(123)
or more probably
class ApiClient
...
protected
def self.uri resource_uri
#uri = resource_uri
end
def get id
# basically whatever code you envisioned for api_client.get_user
end
...
end
class User < ApiClient
uri 'http://path.to.remote/resource.json'
...
def find id
get(id)
end
...
end
User.find(123)
Basic principles: Collect all the shared logic in a class (ApiClient). Subclass that on a per resource basis (User). Keep all the logic in your models, no other part of your system should have to know if it's a DB backed app or if you are using an external REST API. Best of all is if you can keep the integration logic completely in the base class. That way you have only one place to update if the external datasource changes.
As for going the other way, Rails have several good methods to convert objects to JSON. From the to_json method to using a gem such as RABL to have actual views for your JSON objects.
You can get validations by using part of the ActiveRecord modules. As of Rails 4 this is a module called ActiveModel, but you can do it in Rails 3 and there are several tutorials for it online, not least of all a RailsCast.
Performance will not be a problem except what you can incur when calling a remote service, if the network is slow you will be to. Some of that could probably be helped with caching (see another answer by me for details) but that is also dependent on the data you are using.
Hope that put you on the right track. And if you want a more thorough grounding in how to design these kind of structures you should pick up a book on the subject, for example Practical Object-Oriented Design in Ruby: An Agile Primer by Sandi Metz.
I have been tasked with making an existing Java program available via a web service that will be invoked through a PHP form.
The program performs biological simulations and takes a large number of input parameters (around 30 different double, double[], and String fields). These parameters are usually setup as instance variables for an "Input" class which is passed into the the program, which in turn produces an "Output" class (which itself has many important fields). For example, this is how they usually call the program:
Input in = new Input();
in.a = 3.14;
in.b = 42;
in.c = 2.71;
Output out = (new Program()).run(in);
I am looking for a way to turn this into a web service in the easiest way possible. Ideally, I would want it to work like this:
1) The PHP client form formats an array containing the input data and sends it to the service.
2) The Java web service automatically parses this data and uses it to populate an Input instance.
3) The web service invokes the program and produces an Output instance, which is is formatted and sent back to the client.
4) The client retrieves the input formatted as an associative array.
I have already tried a few different methods (such as a SOAP operation and wrapping the data in XML), but nothing seems as elegant as I would like. The problem is that the program's Input variable specifications are likely to change, and I would prefer the only maintenance for such changes to be on the PHP form end.
Unfortunately, I don't have enough experience with web services to make an educated decision on what my setup should be like. Does anyone have any advice for what the most effective solution would be?
IMHO JSON RESFULL will be the best. Look here http://db.tmtec.biz/blogs/index.php/json-restful-web-service-in-java
If your program is stand alone java use jetty as an embedded web server.
If the application is already running as a web application skip this.
The second phase is creating web service. I'd recommend you restful web service. It is easier to implement and maintain than SOAP. You can use XML or JSON format for data. I'd probably recommend you JSON.
Now it is up to you. If you already use some kind of web framework, check whether it supports REST. If you do not use any framework you can implement some kind of REST API using simple servlet that implements doPost(), parses input (JSON) and calls implementation.
There are a lot of possibilities. You should search for data serialization formats and choose the most suitable for this purpose.
One possibility would be to use Protocol Buffers.
I'm building an application where I have my default webpage as 'index.jsp' which consists of a list of <stripes:link...> tags, to link out to my various actionBeans (to their defaulthandlers).
As my application evolves and gathers more actionBeans I'm going back and adding in a new link to them : is there a way to automate this - considering that the stripes framework (I believe) iterates through all the actionBeans when it loads up - is there a way to ask the framework for this information ?
The ActionResolver interface has several methods you could use, including getActionBeanClasses()
StripesFilter.getConfiguration() lets you access the configuration object (and hence the ActionResolver) in a static way.
Here's how to do it:
StripesFilter.getConfiguration().getActionResolver().getActionBeanClasses()
My friend build a web service in java
I build one in .net
I want them to implement the same interface
then in my program change the web.config to point to one or the other.
In my mind this would be done by implementing the same interface. Not sure how it would actually be done...
Perhaps the safest way would be to generate the interface from WSDL. Describe your service(s) in a WSDL document then use 'wsimport -d src WSDL_file' (in Java).
The subtle differences between ASP.NET and Java web services will make this a hard task.
An alternative might be to create an adapter service in front of them, which exposes the same semantic interface, and has service references to both.
This adapter service can be configured to pass on commands to either the Java one or the .NET one based on the same approach of modifying the web.config. IE:
[WebMethod]
public int AddTwoNumbers(int numberA, int numberB)
{
if(useJavaService)
return javaService.AddTwoNumbers(numberA, numberB);
else
return dotnetService.AddTwoNumbers(numberA, numberB);
}
Your application can target this wrapper service, so from your application's perspective you would simply call:
int result = theService.AddTwoNumbers(5, 10);
and your application won't know if its going to hit the Java one or the .NET one.