A while ago I was tasked with adding readiness checks for a Django App. This wasn’t as straight forward as I had hoped, so here’s a tutorial for the next person who has to do this.
The very first thing you need to do is add a new Middleware, say, HealthCheckMiddleware
to your Django app. Adding an API via a middleware and not a view might seem strange at first, but it’s important that you do this, because your readiness check must be executed before anything else, including Django’s inbuilt middleware chain. The skeleton for the middleware will look like:
In your settings.py
, make sure this middleware is executed before everything else by adding it to the top of the list of the middlewares:
The next step is to write code to handle the request itself in the middleware. Readiness usually means that your app is up and can connect to the database. Since this API is going to be called pretty frequently by App Engine, we need to make sure the operation is as light as possible:
The final step is to tell Google App Engine how and when to call this API. Add the following to your app.yaml
:
You should consider tweaking these values. For an explanation of what they mean, check out the docs here.
Unit Tests
Nothing is complete without adding unit tests. To do this, we’ll add 2 unit tests, one that tests if the API returns 200 OK on a successful connection to the database, and a test for checking if there’s no connection to the database (and if the 503 is indeed being returned). Simulating the broken database postgresql connection in Django was a little tricky, since I couldn’t find documentation online, and using tools like destroy_test_db
freaks out the tests as Django thinks something has gone wrong. I was stuck for quite a while on this when my mentor suggested this great idea of passing a database connection object to the middleware, so it can use that instead of using the default connection
object. Since we now control what connection the middleware uses, we can pass a mock database object to it (and break it using a ``side_effect`). Using mocks revealed a host of new Google search results, compared to what I was searching (and struggling with) before.
Add the following code to your tests.py
:
And that’s it! You can see if it worked fine by running python manage.py test tests.HealthCheckMiddlewareTestCase
. You can now be rest assured that App Engine will only route traffic to your instance only when it can successfully connect to your database!