Skip to content

Instantly share code, notes, and snippets.

@denys281
Last active March 22, 2017 10:44
Show Gist options
  • Save denys281/74083d26c115fda33516cc0aed6cbe20 to your computer and use it in GitHub Desktop.
Save denys281/74083d26c115fda33516cc0aed6cbe20 to your computer and use it in GitHub Desktop.
task

Task (level1)

REST service Create a RESTful stand alone web application that is able to persist collections of GPS points (collection in JSON format). These collections are called traces. You can download sample traces from here.

Keep in mind that this web application should work for a large amount of users and that it is likely to receive about 10 times more read than write requests.

This is an example trace:

[{ "latitude": 32.9377784729004, "longitude": -117.230392456055 },
{ "latitude": 32.937801361084, "longitude": -117.230323791504 },
{ "latitude": 32.9378204345703, "longitude": -117.230278015137 },
{ "latitude": 32.9378204345703, "longitude": -117.230239868164 },
{ "latitude": 32.9378318786621, "longitude": -117.230209350586 },
{ "latitude": 32.9378814697266, "longitude": -117.230102539062 },
{ "latitude": 32.9378890991211, "longitude": -117.230072021484 },
{ "latitude": 32.9379081726074, "longitude": -117.230018615723 },
{ "latitude": 32.9379005432129, "longitude": -117.22998046875 },
{ "latitude": 32.937931060791, "longitude": -117.229949951172 },
{ "latitude": 32.9379615783691, "longitude": -117.229919433594 }]

Goals:

you can use any database you like you should use the Ruby language for your implementation you may use any framework or gem implement all actions to perform CRUD on the restful resource "trace" use the JSON format from above for the interface the database design is up to you Hints:

you can use a browser extension like postman or restclient you can use the command line tool curl to do the requests

$ curl -i -X PUT -d @/tmp/trace1.json http://localhost:3003/traces/1 $ curl -i -X POST -d @/tmp/trace1.json http://localhost:3003/traces

Task (level2)

####It's all about the distance Good job! Our requirements have changed slightly. The frontend service that uses your web application needs the distance traveled for each point. So we need to add that field to the response.

Here is an example of the new response format for the read action:

[{ "latitude": 32.9377784729004, "longitude": -117.230392456055, "distance": 0},
{ "latitude": 32.937801361084, "longitude": -117.230323791504, "distance": 6},
{ "latitude": 32.9378204345703, "longitude": -117.230278015137, "distance": 11},
{ "latitude": 32.9378204345703, "longitude": -117.230239868164, "distance": 15},
{ "latitude": 32.9378318786621, "longitude": -117.230209350586, "distance": 18},
{ "latitude": 32.9378814697266, "longitude": -117.230102539062, "distance": 29},
{ "latitude": 32.9378890991211, "longitude": -117.230072021484, "distance": 32},
{ "latitude": 32.9379081726074, "longitude": -117.230018615723, "distance": 37},
{ "latitude": 32.9379005432129, "longitude": -117.22998046875, "distance": 41},
{ "latitude": 32.937931060791, "longitude": -117.229949951172, "distance": 46},
{ "latitude": 32.9379615783691, "longitude": -117.229919433594, "distance": 50}]

As you can see, the distance at each point is cumulated. You can see the pseudo algorithm to calculate the distance here: distance of point3 = (distance between point2 and point3) + distance of point2

Goals:

the create and update actions use the old format as input the read action should respond with the new format already persisted traces should also respond with the new format without reimporting them

Task (level3)

Into the sky and beyond

Well done! Our frontend guys are very happy. But, there is more work to be done.

Every second customer support request sounds something like this: "Your new feature is awesome, but it would be so cool to have elevation data with each trace." So our product managers decided that we should fullfil this wish.

The great thing is, we already have a web service that provides the needed data.

There are 2 methods available:

Single request url: http://codingcontest.runtastic.com/api/elevations/:latitude/:longitude http-method: GET parameters: replace :latitude and :longitude with the actual values example: http://codingcontest.runtastic.com/api/elevations/48.234/12.422134 response: elevation as string Bulk request

url: http://codingcontest.runtastic.com/api/elevations/bulk http-method: POST http-headers: Content-Type=application/json body: trace as json (both formats from above are valid) example: curl -i -H "Content-Type: application/json" -X POST -d '[{"longitude":14.190597534179688,"latitude":48.21848040202353},{"longitude":48,"latitude":14}]' http://codingcontest.runtastic.com/api/elevations/bulk response: json array with elevations in same order of the requested points (example: "[684,672]") Here is an example of the new response format for the read action:

[{ "latitude": 32.9377784729004, "longitude": -117.230392456055, "distance": 0, "elevation": 4139 },
{ "latitude": 32.937801361084, "longitude": -117.230323791504, "distance": 6, "elevation": 4139 },
{ "latitude": 32.9378204345703, "longitude": -117.230278015137, "distance": 11, "elevation": 4139 },
{ "latitude": 32.9378204345703, "longitude": -117.230239868164, "distance": 15, "elevation": 4139 },
{ "latitude": 32.9378318786621, "longitude": -117.230209350586, "distance": 18, "elevation": 4139 },
{ "latitude": 32.9378814697266, "longitude": -117.230102539062, "distance": 29, "elevation": 4139 },
{ "latitude": 32.9378890991211, "longitude": -117.230072021484, "distance": 32, "elevation": 4139 },
{ "latitude": 32.9379081726074, "longitude": -117.230018615723, "distance": 37, "elevation": 4139 },
{ "latitude": 32.9379005432129, "longitude": -117.22998046875, "distance": 41, "elevation": 4139 },
{ "latitude": 32.937931060791, "longitude": -117.229949951172, "distance": 46, "elevation": 4139 },
{ "latitude": 32.9379615783691, "longitude": -117.229919433594, "distance": 50, "elevation": 4139 }]

Goals:

find an elegant and efficient way to communicate with the elevation service the create and update actions use the old format as input the read action should respond with the new format old traces should also respond with the new format without reimporting them

Task (level 4)

The truth

Finally, the new web application is running, everybody is happy with it. But, for how long? Its time to answer some crucial questions:

Does it scale? Will it work for thousands of request per minute? Will it be able to store all the data for the next 5 years? Is your solution flexible enough to cope with change requests? Ask yourself these questions and answer them. Point out the strengths and weaknesses of your solution. What else do you think would be important for a highly available and scalable web application?

If you still have time, you could also think of a way to load test your application and post the results and an interpretation of the data.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment