RavenHQ and ASP.NET MVC – Moving your Data to the Cloud using AppHarbor

Abstract: In this article, we will create an ASP.NET MVC application called ChirpyHQ and deploy it on the Cloud through AppHarbor. This application is using RavenHQ as its backend.

RavenHQ is a hosted RavenDB solution that relieves you from the responsibility of managing a RavenDB server. Your data is managed in the cloud. You have flexible hosting options based on your needs.

We continue to use our Twitter clone Chirpy in this post, but with one change. We didn’t realize Chirpy was an awesome codeplex project owned by a different team[thanks to thecodejunkie for letting us know that]. To avoid confusion we will be referring to our twitter clone as ChirpyHQ going forward.

RavenHQ seems like a perfect idea for our app since we would like a backend system that scales as ChirpyHQ grows in popularity and a cloud based service is perfect for our needs.

Currently RavenHQ is in Beta and the way to participate is to register your application on AppHarbor and use RavenHQ as an Add-On. So we will register and deploy ChirpyHQ to AppHarbor as well.

Note: When introducing ChirpyHQ in the previous article, we had used a standard Repository pattern. Since then, our readers have commented on how RavenDB apps don’t really need a Repository. Use of patterns is as much an opinion as it is a best practice. We encourage people to choose horses-for-courses. So in this article, we will see the same app using a slightly different pattern.

b. The Document Store initiation code needs to supply the API Key. Thus the original code for initializing DocumentStore changes from

to

c. We have removed the call to EnsureDatabase(databaseName). This is because currently AppHarbor limits you to have one Database per App Installation. So if you have any API calls that depend on databaseName, you’ll need a version without the databaseName. RavenHQ uses the ‘default’ database internally in such cases.

d. Also we are using a connection string parser that pulls out the ApiKey and the Url and passing it to the DocumentStore on instantiation.

Step 10: With that bit of plumbing done, we are all set to deploy our code. But unlike regular web-hosts, AppHarbor can automatically pull code from the popular code repositories like GitHub, BitBucket and CodePlex. It involves a simple hookup process, described below

a. From AppHarbor application console

i. Click on “Build URL” (it’s a Flash button that copies the URL into clipboard)

ii. Save the copied url somewhere and extract the query parameter ‘Authorization’. Save this for next step.

b. Link with GitHub or Bitbucket repositories

i. Log in to GitHub or Bitbucket and select the repository

ii. Select Admin

In GitHub select “Service Hooks”

In Bitbucket select Services

Provide API key copied from 10.a.ii

Provide the Application Name

For GitHub select the ‘Active’ checkbox

Save Settings

Step 11: Now commit the code changes and push them to your remote repository.

Step 12: Switch to the AppHarbor application panel, you will see AppHarbor building and deploying the solution

a. In case of build errors, you can click on the Build Status Row to see the status. In the report, you have a ‘Details’ link that has the build output, check that to determine the exact issue. As seen below, our build failed and it was because of Entity Framework bindings.

b. If there are no errors after the build is successful, it gets deployed within a few seconds.

c. Once deployed, you can click on the ‘Go to your application’ link to see the application running.

d. However we notice a glitch here, the App Title is still ‘Chirpy’ instead of ChirpyHQ. So we will modify it and commit the code and let AppHarbor do it’s magic as we can see in the images below

Code Walkthrough – Dissecting ChirpyHQ

In this code sample, we will see an implementation of a ‘repository-less’ pattern. The idea is very simple, RavenDB persists POCOs so why need a heavy repository layer to wrap data extraction. There are arguments in favor and against. I would rather let you pick what’s best for you. In the previous sample, we have already seen what the proposed Repository should look like.

The RavenController

This is a controller class that acts as our base controller. All MVC controllers in our application derive from it.

The OnActionExecuting method is overridden and RavenSession is initialized at this point

The OnActionExecuted method is overridden and the RavenSession persists all change if there are no errors. It is disposed off thereafter.

By deriving all our controllers from RavenController, we ensure that we have a RavenSession ready whenever a Controller action is invoked.

The Home Controller

The HomeController has three Actions, Index (GET), Tag (GET), Search (POST and GET).

Get Index

The Index action simply gets all the Chirps

Note: This is heavily dependent on RavenDB’s safe by default behavior and will not return a million rows of data if present.

Get Tags

The Tags action gets all the Tags and their total count. This uses the Index that we created earlier.

Get Search

This simply returns the Search view.

Post Search

This posts the search term applied and retrieves back all tweets with the given search text in the tag only. However it’s an exact match search. Partial text searches are not honored.

The Administrator Controller

The Administrator is a simple CRUD controller that does the basic CRUD operations on RavenDB. Currently the Home page only navigates to the Create action on the Administrator controller. Rest of the actions doesn’t have a UI in the sample.

Committing to Git and AppHarbor Deployment

With the code all set and our Git+AppHarbor integration ready, we will commit code to Git and it will get automatically pulled into AppHarbor.

Make sure you have the web.config’s RavenDB connectionString set to a non-production URL. AppHarbor will automatically transform the live URL onto this connectionString as long as it is called “RavenDB”.

MVC3, the second Solution and AppHarbor Deployment

In my previous post, some readers were unable to open the web project because of the MVC4 Beta dependency. We understand not everyone lives on the bleeding edge. Last time the community jumped in and helped us with an MVC3 version. This time we will provide the MVC3 version too. We create a separate solution called ChirpyHQ.Mvc3 into which we add an MVC3 Internet web project, move the views, controllers and composition root over and bingo, we have an MVC3 version that looks pretty much like the MVC4 version.

Now you are wondering how will AppHarbor pick which solution? I had the same doubt and @AppHarbor responded with this reference. What it basically means is, if you have two or more solutions, it tries to find AppHarbor.sln first. If not, it tries the ‘Application Slug’.sln . In our case we gave the Slug Name in GitHub is ChirpyHQ so the default MVC4 version will be picked up. If you want to test for MVC3 you can rename the csproj file OR change the slug in the build environment to ChirpyHQ.Mvc3.sln

Conclusion

The app that we discussed here is deployed on http://chirpyhq.apphb.com/ through AppHarbor. It is running RavenHQ as its backend. RavenDB is a scalable document database in it’s own right, but with RavenHQ service it is now available (in Beta currently) for use as a flexible service that grows as per your requirements, without you having to keep up with new hardware or software.

The entire source code for this article is on Github. You can fork it, clone it or download the zip. Have fun with RavenDB and RavenHQ!

Sumit is a .NET consultant and has been working on Microsoft Technologies since his college days. He edits, he codes and he manages content when at work. C# is his first love, but he is often seen flirting with Java and Objective C. You can follow him on twitter at @sumitkm or email him at sumitkm [at] gmail

User Feedback

Comment posted by
Martin
on Tuesday, May 15, 2012 11:46 AM

Thanks for introducing me to Ravenhq and Appharbor! All this makes me think that ASP.NET development has come a long way!

Comment posted by
Pete Chorey
on Tuesday, May 15, 2012 12:07 PM

Does Appharbor support local storage yet? My app doesn't seem to work on AppHarbor

Comment posted by
Sumit
on Tuesday, May 15, 2012 3:32 PM

@Martin Thanks, glad you enjoyed the article.
@Pete By local storage if you mean write permissions to your application folder, yes, it does allow that. Go to Settings of your application and select the "Enable write access..." checkbox.

If you can elaborate on the exact issue/error/exception maybe we can try and analyze it.

Comment posted by
Moiz
on Friday, May 18, 2012 12:27 PM

This is the best article i have ever came across all the sites that i searched for :) Keep going...