Friday, May 6, 2011

Should I RESTify my RPC calls over HTTP?

We have HTTP webservices that are RPC. They return XML representing the object the either retrieved or created. I want to know the advantages (if any) of "restifying" the services.

One thing I see is that we don't need representations for EVERY resource and we don't need to support all operations (GET, PUT, POST, DELETE) on all resources either. Basically my question is this.

Convince me that I should be using restful services instead of RPC over HTTP and what would those restful services should be?

From stackoverflow
  • For one its all about semantics, a URI is a Uniform Resource Indicator. HTTP provides Methods to GET, POST, PUT, DELETE a resource. HTTP headers specify in which format i want to recieve or send the information. This is all readily available through the HTTP protocol.

    So you could reuse the same URL you use for HTML output to get XML, JSON in a way that HTTP was meant to be used.

    XML-RPC and SOAP are based on calling methods that are described by an XSD or WSDL file whilst REST is based on getting/modifying resources. The difference is subtle but apparent. The URL soully describes the resource and not the action as is often the case with SOAP and XML-RPC.

    The benefits of REST are that you can utilize HTTP Verbs to modify a resource as suppose to a Method call that could be named create/new/add etc etc, Meaningful HTTP status codes instead of different kinds of error responses & Being able to specify different formats on the same resource in a standard way.

    You also don't have to accept ALL the verbs on a RESTful resource, for example if you want a read-only resource just return a 405 status code Method Not Allowed on any verb which isn't GET.

    Should you redo your RPC calls to REST ? No i dont think so the benefits don't outweigh the development time. Should you learn REST when setting up a new Webservice ? Yes i personally do think so, consuming a REST resource will feel alot more natural and can grow much more rapidly.

    EDIT

    Why I feel REST wins over XML-RPC/SOAP is that when developing websites you already aggregate all the neccessary data for the output to html, you also write validating code for POST bodies. Why should you change to a different protocol just because the transport markup changes ?

    This way when you design a new website (language agnostic) if you really think of URI's as resources you basically use your URI's as method calls with the HTTP Verb prefixing the method call.

    I.e A GET on /products/12 with an HTTP Header Accept: application/json; basically (imaginary) translates to getProducts(12,MimeType.Json).

    This 'method' then has to do a couple of things

    1. Check if we support Json as a mimetype. (Validate Request)
    2. Validate Request Data
    3. Aggregate data for product 12.
    4. Format to JSON and return.

    If for some reason in the next 4 year YAML is going to be the next big craze and one of your consumers wishes to talk to you in that way this MimeType is plugged in alot more easy then with regular webservices.

    Now product 12 is a resource you most likely also want to accept html mime-types on to display said product but for a URI like /product/12/reviews/14/ you don't need an html counterpart, you just want your consumers to be able to post to that URL to update(PUT)/delete(DELETE) their own review.

    In thinking of URI's strictly as resources, not just a location of a web page, and these resources in turn combined with the HTTP request to method invocations on the server side leads to clean (SEO friendly) urls and (more importantly?) ease of development.

    I'm sure there are frameworks in any language that will automatically do the mapping of URI's to method invocations for you, I can't recommend one since I usually role out my own.

    ASP.NET MVC also works on the same principle but in my opinion doesn't produce RESTful URI's. ASP.NET MVC makes the verb part of the URI by default having said that it's good to note that by no means does ASP.NET MVC force this (or anything for that matter) upon you.

    If your going to choose a framework in the very least they should:

    1. Bind URI's to methods on the server
    2. Support Object to JSON/XML etc serialization, it's a pain if you have to write this yourself although dependant on the language not neccessary all to difficult.
    3. Expose some sort of type safe Request helpers to help you determine what was requested without parsing the HTTP Headers manually.
    Mike Pone : This is good. Can you comment more on why REST is better for new webservices over XML-RPC?
    Martijn Laarman : Sure. I feel like I ranted a bit but I hope it explains my position better.
    Martijn Laarman : I see your a JSP developer, I have heard good stories from Jersy https://jersey.dev.java.net/ form people who've used it to implement REST with JSP. It also supports JAXB to bind XML/JSON requests automatically to objects.
  • Try taking the verbs out of your URLs:

    Wahnfrieden : URI construction has nothing to do with REST
  • Query strings shouldn't be used for accessing a resource in a hierarchical, non-query manner. Query strings are usually ignored when caching, which is dangerous and slow.

Detect when UITableViewCell goes off the screen

Hi,

I'm implementing a rich UITableView with custom created UITableViewCell, I show these on the screen in one fashion, but once they go off the screen I want to take a note of that, since the second time they come on I would like them to get displayed in a different manner. Think auto "mark as read" when going off the screen.

I've been looking for some way to detect when a cell goes off the screen (get's dealloc'ed or dequeued or equivalent), preferably in the :UITableViewController class to make a quick note of the [indexPath row], but in the :UITableViewCell is equally as good.

I haven't been able to do this in any standard way ... counting the times it appeared seems out of the question as I do multiple reloadData calls on the table.

Anyone any ideas? This seems a bit tricky :)

From stackoverflow
  • I think I would try periodically checking the indexPathsForVisibleRows property of the UITableView. From the largest index path, you can deduce that all previous rows have been scrolled past.

  • I think you could use the

    - (NSArray *)visibleCells
    

    method for your UITableView. This returns an array of all cells that are visible. You can then mark any data that is "not visible" (i.e. not in this array) in the way you want, such that when you scroll back to it, it has been updated.

    Hope that helps

  • Are you sure a cell going offscreen is exactly what you want to catch? If you want to mark items as read, this does not seem like a proper way to do it. For example, I might scroll though the table really fast, and I would be very surprised if you marked all of the stuff as read.

    As for the technical part, simply keep a list of cells that are on screen (cellForRowAtIndexPath should add cells to that list), and in scrollViewDidScroll delegate method check if any of them are no longer visible.

    Another possible idea: I remember there is prepareForReuse method on the cell. Not sure when it is called, though.

How to set an ints Hex Literal from a string,

Im attempting to load a hex literal from an xml settings file, I can parse the xml just fine and get the required string from the file,

but i cant seem to get it to set an int variables value :/

Code:

    int PlayerBaseAddress = System.Convert.ToInt32(ConfigLoader.GetSetting("PlayerBaseAddress"));
    // Input string was not in a correct format.

    public static string GetSetting(string Val)
    {
       // This loads from the xml file, Pretend its hardcoded to return a string of 0x17EAAF00
    }

    int PlayerBaseAddress = 0x17EAAF00; // This works.
From stackoverflow

JavaScript to Save As with current date

I have a time sheet form named Timesheet Paperless.pdf I send this form to an employee and tell them to fill their name and employee number in the form. I then ask them to go to File>Save As and name the form INTIALS_TS.pdf . I now would like to a have button with in the form that will open a Save As dialog with the filename INITIALS_TS CurrentDate.pdf under My Documents/Work Files/Time Sheets/. So every new pay period they would click the save button on the form to save the file under the time sheets folder with their intials and the current date the button was pushed. How can I do this in JavaScript?

From stackoverflow
  • Sorry, there's no way to do that with JavaScript.

    The closest solution that comes to mind is open a link to a server-side script that outputs the PDF along with a content-disposition header.

    Content-Disposition: attachment; filename=INITALS_TS.pdf
    

HTML/JSP Doubt, Print date on webpage...

I made a function which displays date on the webpage,, and i uploaded the same onto some server...

But when i changed the date of my system, i noticed that the date is dependent on client machine..

Is it not possible to get the date from actual time server and embed that code into my program..

Hope i am able to explain my doubt.. Please give some solution to this with small sample code..that would be helpful..

Thanks a lot..

From stackoverflow
  • You've written a javascript function which obviously is dependent on the date set in the client

    AGeek : yes, i have written a javascript function which is dependent on date set in the client,, but i want that to be independent of client.. if client changes his date on the system then that would not reflect it on webpage,, is there any logic to solve this...
  • Depending on your server-side language, just use it's date() function which gives the current date/time based on the server clock. Next, format that info and send it to the client as a set value.

    For instance, in php:

    echo date();
    
    AGeek : i have tried this,, it does not take the time of server, rather it takes the time of client machine.. and i have tested this by putting a code on a server, and accessing it to my computer (with date and time changed). but it reflects the date of the client rather server.. so i need to know some website which offer this date etc..
  • Initialize the function with date from the server

    var d = new Date(<%= new SimpleDateFormat("yyyy, M-1, dd").format(new Date()) %>);

    AGeek : giving error... not working!!
    R. Bemrose : What's the error?
    fc : Have you imported `java.text.SimpleDateFormat` and `java.util.Date`
  • If you have written it in javascript, well...that always executes on the client side. If you are calculating date through javascript, its too late, that code is gone.

    To solve this, you would have to make your js function receive data through parameters, and that data should be calculated on the server side.

    You could do something like.

    <%@ page import ="java.util.Date" %><%--Imports date --%>
    <% Date date = new Date();
       String strdate = date.toString();//could be formatted using SimpleDateFormat.
    %>
    
      <!--must be inside a form -->  
      <input type="text" value="javascript:showDate('<%=strdate%>');"/>
    
      <!--must be inside a table-->
      <td>javascript:showDate(<%=strdate%>);</td>
    

    Or more elegantly, get server date in your java class, and write it to request:

    //formattedDate is defined above, in the format you like the most. Could be a 
    //java.util.date or a String
    request.setDate("date",formattedDate);
    

    And then, in your jsp, using for example, JSTL

    <c:out value="${formattedDate}"/>
    

    Or,

    <% //this java code is run on the server side.
        String strdate = (String)request.getAttribute("date"); 
     %>
    <%=strdate%><!-- prints strdate to jsp. Could put it in a table, form, etc -->
    

    EDIT: In response to your comment, you should:

    <%--Imports java packages --%>
    <%@ page import ="java.util.Date" %>
    <%@ page import ="java.text.SimpleDateFormat"%>
    
    <%-- Java code --%>
    <% Date date = new Date();
       Calendar calendar = Calendar.getInstance(TIME_ZONE).setTime(date);
       SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yy");
       String strdate = sdf.format(calendar.getTime());
    %>
    
    <html>
     <body>
     <!-- Does not need to use javascript. All work is done on the server side.-->
     <table>
       <tr>
         <td><%=strdate%></td>
       </tr>
     </table>
     </body>
    </html>
    

    I have no idea what your time zone is, but I'm sure you do. Calendar.getInstance() takes an instance of TimeZone as a parameter. That should do it

    Take a look:

    http://java.sun.com/javase/6/docs/api/java/util/TimeZone.html

    http://java.sun.com/javase/6/docs/api/java/util/Calendar.html

    Interesting link about JSP

    AGeek : i was not able to run your example accurately, but i can imagine ur program will give me the time of the server on the webpage, if you can write the code complete,, using inside a table will do...
    AGeek : hi sir,, your code worked.. but one problem now i am facing is that the server is based at US, and i am from diff. country so time not matching,, not thought of this before,, so can i code something or get the time from some other website everytime the page loads, and comes up with my country's time..
    Tom : You should take a look at the java.util.Calendar class, particularly at the method setTimeZone()
    AGeek : plz specify some example of TIME_ZONE.. lets say, how to write the timezone for GMT+3.5 in the programm..
    Tom : From TimeZone Class, see link above (TimeZone.html) Hours must be between 0 to 23 and Minutes must be between 00 to 59. For example, "GMT+10" and "GMT+0010" mean ten hours and ten minutes ahead of GMT, respectively.
    AGeek : Thnx a lot sir,, i solved my doubt.. All because of u, i achieved it.. thnx..

Hidden features of msbuild

I have an interest in msbuild this week. I'm cleaning up a lot of extremely complex build scripts. Digging in surprises me with how much it can do - msbuild is sort of a hidden feature of .NET programming in itself.

In the SO convention that questions must have answers, in a few days or a week, I'll mark the most useful or coolest hidden feature(s) as accepted.

   let bestAnswer suprise slick useful = (surprise + slick + 2*useful)

Definition of useful: I'm updating existing msbuild scripts that: package (zip files) websites and utilities, CC.NET integration, launch tests (UT + selenium), build databases. I'm adding (new targets, even more useful): deploy to VMWare virtual servers, chained builds (fast build immediately, queue slow tests). If you refer to an external library (like MSBuild community tasks), it would be nice to know how to get it.

Some msbuild surprises I've already found.

  • Hello world using the Message task and Properties.
  • Using msbuild as an installer for an extremely complex server product. MSB community tasks managed IIS server setup. The WriteLinesToFile and XmlUpdate tasks wrote server specific configuration files. If you've work with MSI, you'll know that anything is better than MSI for installation.
  • For newbies: CSProj and Vbproj files are the same as msbuild "proj" files. To edit directly: Unload your csproj or vbproj, then right click project and select edit. This is nicer and more powerful than working with clunky pre-build / post-build events.
  • MSBuild comes with the generic .NET installation. Unlike other fancy tools, you can use it on a totally clean server / desktop.

Here is msbuild Hello World After I wrote it, I found the MSDN hello world.

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build;Test" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
       <Who>World</Who>
  </PropertyGroup>
  <Target Name="Hello">
    <Message Text="Hello, $(Who)" Importance="high" ></Message>
  </Target>
  <Target Name="Build" DependsOnTargets="Hello"/>
  <Target Name="Test"/>
</Project>
From stackoverflow
  • MSBuild has a number of nice features. I like

    recursive file specs

    <Files Include="$(src)\**\*.cs" Exclude="$(src)\**\*test.cs" />
    

    Batching and Item Metadata

    <ItemGroup>
     <F Include="SampleApplication.t">
        <Version>1</Version>
    </F>
     <F Include="SampleApplication2.t">
        <Version>1</Version>
    </F>
    <F Include="SampleApplication3.t">
       <Version>2</Version>
    </F>
    </ItemGroup>
    <Target Name="Build">
    <Touch Files="%(F.FullPath)" AlwaysCreate="True" 
            Condition=" '%(F.Version)' > '1' ">
    <Output TaskParameter="TouchedFiles" ItemName="CreatedFiles"/>
    </Touch>
    <Message Text="Created files = @(CreatedFiles)"/>
    <Message Text="%(F.Identity) %(F.Version)"/>
    </Target>
    

    Target level dependency analysis

    <Target Name="Build"
               Inputs="@(MyItems)"
               Outputs="@(MyItems -> '$(MyItems)\%(filename).dll'">
    
    Marc Gravell : The recursive ** is a trick I use for sharing code between frameworks (CF/Silverlight/.NET/etc) - very useful.
  • You can reference one msbuild file from within another. All of our targets, such as those for running NCover, SourceMonitor, Duplo, etc. are within a common targets file. For each project, we create an msbuild file with a PropertyGroup and ItemGroup section, followed by an include to the common targets. This guarantees that all of our builds will run the same set of analysis tasks and save us time writing the scripts.

    • I have found the MSBuild Extension pack to be incredibly useful. The documentation is very well organized and easy to find the info you need.

    • They have a section in configuring intellisense for build files, that can be found here

    • Attrice has an incredible tool that I use often if I need to work on build scripts. What makes it worth your while to try it out, is that it has a debugger that will show you the dependent tasks, as it executes your build script, with auto's and watch variables while it is running the build script. Microsoft Build Sidekick v2.3

    • Setting SVN to quiet, this feels to me to have increased the speed of the build process a lot. Adding the following to your MSBuild.Community.Tasks.Subversion.SvnExport will run the build without logging each and every file that it gets out of SVN

      Arguments="--force -q"

  • Use the /M command-line parameter to enable usage of all available CPU cores.

  • Hi, This is not really a hidden feature but I think that batching is very powerful when understood.

    For more information you can read my related blog entries at:

Question on modifying this custom iterator

I have the below code, which iterates over a list based on a custom algorithm:

        public static IEnumerable<TItem>
MakeCustomIterator<TCollection, TCursor, TItem>(
this TCollection collection, // Extension method of the collection used (eg List<T>)
TCursor cursor, // An array of ints which holds our progress
Func<TCollection, TCursor, TItem> getCurrent,
Func<TCursor, bool> isFinished,
Func<TCursor, TCursor> advanceCursor)
        {
            while (!isFinished(cursor)) // While we haven't reached the end of the iteration......
            {
                yield return getCurrent(collection, cursor);
                cursor = advanceCursor(cursor);

            }

        }


     var matrix = new List<List<double>> {
     new List<double> { 1.0, 1.1, 1.2 },
      new List<double> { 2.0, 2.1, 2.2 },
      new List<double> { 3.0, 3.1, 3.2 }
      };

     var iter = matrix.MakeCustomIterator(
     new int[] { 0, 0 },
     (coll, cur) => coll[cur[0]][cur[1]],
     (cur) => cur[0] > 2 || cur[1] > 2,
     (cur) => new int[] { cur[0] + 1,
       cur[1] + 1 });



            foreach (var item in iter)
            {

            }

When I use this code, it will get 1.0 and then 2.1 (diagonally below, in the next list). Is it possible to go from 1.0 to 1.1 in the first link? Or possible to go vertically down from 1.0 to 2.0?

Note: This code snippet is from Accelerated C# 2008.

Thanks

From stackoverflow
  • You just need to change the idea of what "advancing" means (potentially along with what "finished" means). For example, to just go "down" you'd use:

    var iter = matrix.MakeCustomIterator(
         new int[] { 0, 0 },
         (coll, cur) => coll[cur[0]][cur[1]],
         (cur) => cur[0] > 2 || cur[1] > 2,
         // Increase the row, but stay on the same column
         (cur) => new int[] { cur[0] + 1, cur[1] });
    

    To go "along":

    var iter = matrix.MakeCustomIterator(
         new int[] { 0, 0 },
         (coll, cur) => coll[cur[0]][cur[1]],
         (cur) => cur[0] > 2 || cur[1] > 2,
         // Stay on the same row, but increase the column
         (cur) => new int[] { cur[0], cur[1] + 1 });
    

    It would be trickier to go "along then down" but feasible:

    var iter = matrix.MakeCustomIterator(
         new int[] { 0, 0 },
         (coll, cur) => coll[cur[0]][cur[1]],
         (cur) => cur[0] > 2,
         // Stay on the same row if we can, otherwise move to next row
         (cur) => cur[1] == 2 ? new int[] { cur[0] + 1, 0 }
                              : new int[] { cur[0], cur[1] + 1});
    
    dotnetdev : Thanks for that!