Your SlideShare is downloading. ×
Building a scalable API with                      Grails         Greach – 2013-01-26             Tanausú Cerdeña      @cho...
What you can expect from this talk•   A story of an API creation on Grails.•   Decisions made and the reasons behind.•   P...
About me• Tanausú Cerdeña (@chozero)• Sysadmin background.• Grails user for two years.• Co-founder and CTO at Geosophic.
Let’s get some context firstOnline services for mobile games:• Gaming features: Leaderboards, player  matching…• Data trac...
Let’s get some context firstOnline services for mobile games:• Gaming features: Leaderboards, player  matching…• Data trac...
Why Grails?1. Productivity. Geosophic started as   an MVP.2. Java experience on the team.3. It’s fun to use! (+15% develop...
Our development environment• Grails 2.1.1 / Groovy 1.8.8• STS / vim. Trying to move to Intellij (thanks  doomsday!!)• Depl...
Overview of architectureAndroid              iOS SDK                 SDK          HTTP API                       Dashboard...
API Controllers• Lightweight:   • Validate parameters   • Call required services   • Compose responses
API Controllers
API DesignTop-down design:• URLs.• (HTTP) Methods (Fully REST  compliant?)• Response format.• Versioning.• Authentication.
API Design: URL schemahttp://{baseURL}/{version}/{feature}/{item}/{action?}http://api.geosophic.com/v1/leaderboards/leader...
API Design: Versioning optionsIn the URL path?   http://my.api.com/v1/endpointAs a URL parameter?   http://my.api.com/endp...
API Design: Versioning optionsIn the URL path?   http://my.api.com/v1/endpointAs a URL parameter?   http://my.api.com/endp...
API Design: Versioning issues• Scarcity of resources to handle different  versions.• Backwards compatibility?• Our first c...
HTTP methodsOur API model doesn’t match perfectly with a CRUDmodel so no fully REST API.• GET: Retrieving info.  • Get a l...
API Design: URL mappings
API Design: Response formatOnly JSON. No XML{    meta: {       apiVersion: “1.0.1”,       code: 400,       errorType: “Use...
API Design: Response format
Rendering responserender as JSON:• We have a mix of domain classes and other   objects to render.• Write custom JSON Marsh...
Rendering JSON response
Rendering JSON response
DRY in our API ControllersWe have some common code for all our APIendpoints:• Authentication.• API usage tracking.• Common...
@Mixin: ApiController
@Mixin: ApiController
@Mixin: ApiControllerAlso includes some helper methods:
@Mixin: Issues• Class reloading when in development
API Design: Authentication• (consumer key, consumer secret) per  client.• Consumer key used to identify the  client (sent ...
API Design: Authentication• Some plugins implementing clients,  but no suitable (for us) server  implementation (maybe we ...
API Design: Handling errors• 400 handled by each Controller• 500 handled by ErrorController  (mapped in UrlMappings.groovy)
API Design: Handling errors
Measuring API usage• In ApiController beforeInterceptor• Fire and forget (runAsync in the  service)• Now to MySQL, moving ...
Measuring API usage
Testing• Test Api Controllers as any other  controller• All bussiness logic in Services• Remember to include the Mixin:
Testing
Performance considerations• No GSPs but JSON so quite fast.• Asynchronous tracking helps.• Difficult to cache (except for ...
Some performance figures• 1 EC2 small instance(1.7GB RAM)• API + Services + Dashboard• 90K users, 7K daily active.• Throug...
Bottlenecks• Database: MySQL• Redis for most read data:  • Gaming features (leaderboards)• Evaluating metrics storage:  • ...
Next steps• Improve the API usage tracking.• Spock.• See what we can contribute (Auth? API  usage?)• Looking for a nice lo...
¡Thanks!¿Questions and/or suggestions?
Upcoming SlideShare
Loading in...5
×

Building a scalable API with Grails

6,418

Published on

Geosophic is a platform of online services for mobile games. It offers both user engagement features (such as leaderboards and achievements) and analytics.
In this talk I would like to share with you our experience building this platform with Grails with the goal to support a big load. I’ll focus on the system architecture, the problems we have found and how we are solving them.

Published in: Technology

Transcript of "Building a scalable API with Grails"

  1. 1. Building a scalable API with Grails Greach – 2013-01-26 Tanausú Cerdeña @chozero | @geosophers
  2. 2. What you can expect from this talk• A story of an API creation on Grails.• Decisions made and the reasons behind.• Pitfalls.• We’re learning as we go.
  3. 3. About me• Tanausú Cerdeña (@chozero)• Sysadmin background.• Grails user for two years.• Co-founder and CTO at Geosophic.
  4. 4. Let’s get some context firstOnline services for mobile games:• Gaming features: Leaderboards, player matching…• Data tracking: levels played, session duration…• Monetization: Performance ad serving.
  5. 5. Let’s get some context firstOnline services for mobile games:• Gaming features: Leaderboards, player matching…• Data tracking: levels played, session duration…• Monetization: Performance ad serving.
  6. 6. Why Grails?1. Productivity. Geosophic started as an MVP.2. Java experience on the team.3. It’s fun to use! (+15% developer happiness).
  7. 7. Our development environment• Grails 2.1.1 / Groovy 1.8.8• STS / vim. Trying to move to Intellij (thanks doomsday!!)• Deployed to AWS (Elastic Beanstalk).• Team of 3 developers: • 1 backend, 1 frontend, 1 mobile • Everyone touches everything.
  8. 8. Overview of architectureAndroid iOS SDK SDK HTTP API Dashboard (Grails) API Controllers Dashboard Controllers Services Domain Objects MySQL Redis
  9. 9. API Controllers• Lightweight: • Validate parameters • Call required services • Compose responses
  10. 10. API Controllers
  11. 11. API DesignTop-down design:• URLs.• (HTTP) Methods (Fully REST compliant?)• Response format.• Versioning.• Authentication.
  12. 12. API Design: URL schemahttp://{baseURL}/{version}/{feature}/{item}/{action?}http://api.geosophic.com/v1/leaderboards/leaderboard/nearesthttp://api.geosophic.com/v1/leaderboards/scorehttp://api.geosophic.com/v1/track/event
  13. 13. API Design: Versioning optionsIn the URL path? http://my.api.com/v1/endpointAs a URL parameter? http://my.api.com/endpoint??v=1Custom HTTP Header? Accept-Version: 1Versioned media types? Accept: application/vnd.myapp-v1+json
  14. 14. API Design: Versioning optionsIn the URL path? http://my.api.com/v1/endpointAs a URL parameter? http://my.api.com/endpoint??v=1Custom HTTP Header? Accept-Version: 1Versioned media types? Accept: application/vnd.myapp-v1+json
  15. 15. API Design: Versioning issues• Scarcity of resources to handle different versions.• Backwards compatibility?• Our first client deployed, a week later, we decided a change on the API.• Mobile clients (apps) don’t update that often.
  16. 16. HTTP methodsOur API model doesn’t match perfectly with a CRUDmodel so no fully REST API.• GET: Retrieving info. • Get a leaderboard• POST: Submitting info. • Send a score. • Submit an event.
  17. 17. API Design: URL mappings
  18. 18. API Design: Response formatOnly JSON. No XML{ meta: { apiVersion: “1.0.1”, code: 400, errorType: “User id required”, msgs: [] }, response: { // Content depends on endpoint }, notifications: { // Future use }}
  19. 19. API Design: Response format
  20. 20. Rendering responserender as JSON:• We have a mix of domain classes and other objects to render.• Write custom JSON Marshaller for some classes.• Register them at BootStrap.groovy.
  21. 21. Rendering JSON response
  22. 22. Rendering JSON response
  23. 23. DRY in our API ControllersWe have some common code for all our APIendpoints:• Authentication.• API usage tracking.• Common parameters validation.
  24. 24. @Mixin: ApiController
  25. 25. @Mixin: ApiController
  26. 26. @Mixin: ApiControllerAlso includes some helper methods:
  27. 27. @Mixin: Issues• Class reloading when in development
  28. 28. API Design: Authentication• (consumer key, consumer secret) per client.• Consumer key used to identify the client (sent as a URL parameter).• Consumer secret to sign the request.• This is (sort of) 2-legged Oauth.
  29. 29. API Design: Authentication• Some plugins implementing clients, but no suitable (for us) server implementation (maybe we didn’t look deep enough?).• Better to use SpringSecurity and customize?• We are feeling more confident and want to contribute this.
  30. 30. API Design: Handling errors• 400 handled by each Controller• 500 handled by ErrorController (mapped in UrlMappings.groovy)
  31. 31. API Design: Handling errors
  32. 32. Measuring API usage• In ApiController beforeInterceptor• Fire and forget (runAsync in the service)• Now to MySQL, moving to Redis
  33. 33. Measuring API usage
  34. 34. Testing• Test Api Controllers as any other controller• All bussiness logic in Services• Remember to include the Mixin:
  35. 35. Testing
  36. 36. Performance considerations• No GSPs but JSON so quite fast.• Asynchronous tracking helps.• Difficult to cache (except for leaderboards). We cache in the service.
  37. 37. Some performance figures• 1 EC2 small instance(1.7GB RAM)• API + Services + Dashboard• 90K users, 7K daily active.• Throughput: ~ 75 rpm (peaks of 200)• Server response time: ~ 160 ms average• Performance tests: up to 450 rpm
  38. 38. Bottlenecks• Database: MySQL• Redis for most read data: • Gaming features (leaderboards)• Evaluating metrics storage: • Redis • Cube (from Square)
  39. 39. Next steps• Improve the API usage tracking.• Spock.• See what we can contribute (Auth? API usage?)• Looking for a nice log viewer solution
  40. 40. ¡Thanks!¿Questions and/or suggestions?

×