Heroku + Gradle + Dropwizard
How to build scalable REST APIs on the Heroku Platform
If you are only looking for the code, you can find it on Github.
Dropwizard is a java framework for developing RESTful web services. It bundles a collection of stable and mature Java libraries together into a simple, light-weight package. With its out-of-the-box support for configuration, metrics, logging and operational tools, it enables teams to focus on getting things done and to ship production-quality web services in short time. My own experience with Dropwizard in the past 2 years has been nothing short of exceptional. We use it to build our services at A. Y. Technologies and I have been preaching now for a long time that Dropwizard is one of the best platforms for building scalable RESTfull APIs.
A few months ago I started on a personal project which brought together Dropwizard with two other favourite platforms: Heroku and Gradle. From Heroku you can expect easy and hassle free deployment and infrastructure management tools and a free tier perfect for projects that are in development and not production ready. Given that PaaS (platform as a service) is growing fast and companies like Citrix GoToMeetings, IFTTT and RedRobin are using Heroku and similar services, you don’t need to worry about migration after you are ready to release.
I soon found out that there are no straightforward tutorials on how to develop and deploy Dropwizard applications with Gradle on Heroku. I learned a lot during the course of this project and I know having a tutorial to guide me would’ve saved me a lot of time; so I thought I would pass on the knowledge. Feel free to use this code to jumpstart your project development with Dropwizard and Gradle deployed on Heroku. Get back to me with feedback on what you would do better. Create issues on Github and I’ll try to answer as much as I can.
If you have used Heroku before, you know that they have limitations on HTTP Responses. Basically your API call should return in 30 seconds or less. That limitation promotes building apps that use web/worker architecture. Your web layer will take care of the API calls. If a request is going to take longer than usual, then you need to have workers run it in the background as a job. The web and the worker are connected via a message queue.
We implement that architecture in our project. Since the web and worker need to share some common knowledge (such as entities, queue information, etc.) we have 3 sub projects:
Both Worker and Web projects are Dropwizard applications. The Web application responds to HTTP requests sent by a client and the Worker application processes long living requests in the background. The rest is pretty straightforward:
The MemoResource handles requests that come from the user (via
/memos endpoint), then adds a message to the queue and returns the memo with status Processing.
The MemoWorker then will be notified of a new job, will take the job, process the memo and update its status. Next time the user requests the memo if the processing is finished they will receive the memo that is processed and ready to go!
You need to have an account with Heroku before you can create an app. Create an account first if you don’t have one.
If you have an account, you need to download Heroku Command Line tool and install it.
To login, you need to use command
heroku login. Follow the steps and you will be logged in to heroku:
heroku login Enter your Heroku credentials. Email: email@example.com Password (typing will be hidden): Logged in as firstname.lastname@example.org
Create an App
You can create an app with any name. It needs to be unique to your account.
heroku create heroku-dropwizard-gradle
As mentioned above, we use PostgreSQL and RabbitMQ. To be able to use those on Heroku platform you need to add them on as add-ons!
Note that the add-ons we use here are free and you can potentially upgrade them to paid add-ons later.
heroku addons:create heroku-postgresql:hobby-dev heroku addons:create cloudamqp:lemur
Set Config – Dropwizard Port
Heroku requires any app deployed on it to listen on a specific port. If the app doesn’t listen to that port in 60 seconds after boot time, the app is considered broken and will not go live. To make sure your Dropwizard server listens to the port that Heroku assigns to your app, you need to set the following configuration:
heroku config:set WEB_OPTS='-Ddw.server.applicationConnectors.port=$PORT'
Deployment on Heroku is done via git. If you are not using git for your project you should!
git push heroku master
By default Heroku workers are scaled to 0 (off). You need to scale up your workers to 1 (still free). In future you can scale worker processes independent of web processes which is great for having a scalable service.
heroku ps:scale worker=1
You can tail the logs and see what’s going on with this command:
heroku logs -t