Giter Club home page Giter Club logo

xmlrpc's Introduction

Xmlrpc for Scala Build Status

This is a Scala library to talk to servers and clients via XML-RPC, originally created to connect to my university servers. This implementation is compliant with the specification.

What is XML-RPC?

Chances are, that if you are reading this, you already know what XML-RPC is. But, for the sake of completeness, here it is the definition from the specification:

XML-RPC is a Remote Procedure Calling protocol that works over the Internet. An XML-RPC message is an HTTP-POST request. The body of the request is in XML. A procedure executes on the server and the value it returns is also formatted in XML.

Despite that more powerful and modern rpc protocols are used nowadays, I have written this to support connection to older servers.

Dependencies

This library uses Spray to connect to any HTTP server. It would be easy to change that if one wants to use another library like Dispatch. You are free to fork this project and make the necesssary changes in Xmlrpc.scala, located in the main package.

Thanks to Scalaz, it offers good feedback in case of any failure with the help of Validation[T]. Validation is applicative, this means that all the errors in the process of deserialization will be accumulated.

Using Shapeless, we solve the problem of writing boilerplate code for any arity of case classes and tuples. If you are more interested in a library for serialization using Shapeless, you can check PicoPickle, an extensible, more powerful library entirely written in Shapeless.

Import to your project

This project is only compatible with Scala 2.11+.

In order to add it to your project, write the following in your build.sbt:

libraryDependencies ++= Seq("com.github.jvican" %% "xmlrpc" % "1.0.1")

What does this solve?

It solves the problem of serializing and deserializing types in a fancy way. Moreover, it does so simpler than other libraries, using the power of type classes and implicits. This technique was proposed by David McIver in sbinary and it's very powerful, being used broadly in json and xml libraries.

Usage

Serializing and Deserializing

A tiny example using case classes. Tuples, Option[T] and roughly any standard type can be used to read and write XML-RPC messages (if you want for some type in particular, please let me know). This example only shows the serialization and deserialization but not the use of invokeMethod. If you are implementing a server, you may use only this feature to reply the client.

import xmlrpc.protocol.XmlrpcProtocol._

// As you see, no boilerplate code is needed
case class Subject(code: Int, title: String)
case class Student(name: String, age: Int, currentGrade: Double, favorite: Subject)

val history = Subject(1, "Contemporary History")
val charles = Student("Charles de Gaulle", 42, 7.2, history)

// The only restriction is to explicitly mark the type
writeXmlRequest[Student]("addStudent", Some(charles))

// This is a confirmation from the server
case class Confirmation(message: String)

// Make sure you always mark the return type
readXmlResponse[Confirmation](<methodResponse>
  <params>
    <param>
      <value><string>{"Ok"}</string></value>
    </param>
  </params>
</methodResponse>)

Connecting to the server

First, import the library:

import xmlrpc.protocol.XmlrpcProtocol._
import xmlrpc.Xmlrpc._

If you don't have an Actor System in scope or you don't have an environment created for Spray, you must set it up:

implicit val system = ActorSystem()
implicit val timeout = Timeout(5 seconds)
import system.dispatcher

Now, we set up the XML-RPC server and invoke any method:

implicit val testServer = XmlrpcServer("http://betty.userland.com/RPC2")
val response: XmlrpcResponse[Int] = invokeMethod[String, Int]("methodName", "Hello World!")

You don't have to explicit the type of the response. If you want to have a Future[Int], you can access the attribute underlying of the response. XmlrpcResponse is a wrapper useful when we want to invoke several methods, because it allow us to use for-comprehensions and chain them.

Issues

At this moment, it's not possible to serialize and deserialize Seq[Any]. For example, you cannot serialize List("a", 1). In case you need this, it's better to use case classes if the appearances of these types are cyclic, e.g. List("a", 1, "a", 1). When I have more time, I would include this functionality in the library.

xmlrpc's People

Contributors

jvican avatar

Watchers

Dan Todor avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.