Transcript
Page 1: Gamers do REST - DjangoCon 2014

Gamers do RESTnot

by Angel Ramboi

Page 2: Gamers do REST - DjangoCon 2014

This is one of our recent graphs of online users.As you can see their number never even comes close to zero.

Page 3: Gamers do REST - DjangoCon 2014

And these guys get really excited during launch time.

Page 4: Gamers do REST - DjangoCon 2014

About Demonware

Dublin

Shanghai

Vancouver

Page 5: Gamers do REST - DjangoCon 2014

What do we do?

We enable gamers to find one another and

shoot each other in the face

Page 6: Gamers do REST - DjangoCon 2014

What do we do?leaderboardsmatchmaking

anticheataccounts management

and more … 70+ services

Page 7: Gamers do REST - DjangoCon 2014
Page 8: Gamers do REST - DjangoCon 2014

We hire superheroes

http://www.demonware.net/jobs

Page 9: Gamers do REST - DjangoCon 2014

Why REST?

interoperability

scalability

Page 10: Gamers do REST - DjangoCon 2014

Tech stack overview

Django 1.6Python 2.7

MySQL 5.6 (sharded)CentOS

Apache+mod_wsgi

Page 11: Gamers do REST - DjangoCon 2014

API design● We tend to follow the REST principles outlined in Roy

Fielding's thesis● GET, POST, PUT, DELETE verbs for API CRUD● HTTP for the communication protocol● JSON for representation● Pragmatic approach

○ “good enough” > perfect

Page 12: Gamers do REST - DjangoCon 2014

API design (example)GET /v1.0/users/1/ HTTP/1.1

Accept: application/json

{

"userName": "cmac1",

"email": "[email protected]",

"firstName" : "Connor",

"lastName" : "MacLeod",

"dateOfBirth": "1518-03-18",

"immortalityAttained": "1536-11-05",

"country": "GB",

"gender": "male",

"link": { "href": "/v1.0/users/1/only-one/" }

}

Page 13: Gamers do REST - DjangoCon 2014

Process and tools

Page 14: Gamers do REST - DjangoCon 2014

Code and deployments

Page 15: Gamers do REST - DjangoCon 2014

YAML 1.2

---

django:

DEBUG: False

ALLOWED_HOSTS: ["*"]

TIME_ZONE: UTC

LANGUAGE_CODE: en-us

USE_I18N: True

SECRET_KEY: “It’s a secret!!!”

TEMPLATE_LOADERS:

- django.template.loaders.filesystem.Loader

INSTALLED_APPS:

- django.contrib.contenttypes

[...]

Cross project&

Validation

App configuration

Page 16: Gamers do REST - DjangoCon 2014

App configurationValidation example

minimum_age = Option(

type={

'type': 'integer',

'valid': [['>=', 0]]

},

default=13,

description='The minimum age of a user this client can create.')

Page 17: Gamers do REST - DjangoCon 2014

{

"title": "Example Schema",

"type": "object",

"properties": {

"username": {

"type": "string",

"pattern": "^[a-z0-9_-]{3,15}$"

},

"age": {

"description": "Age in years",

"type": "integer",

"minimum": 0

}

}

}

JSON validation

http://json-schema.org/

Page 18: Gamers do REST - DjangoCon 2014

{

"title": "Example Schema",

"type": "object",

"properties": {

"firstName": {

"type": "string",

"maxLength": 100

},

"lastName": {

"type": "string",

"maxLength": 100

}

},

"required": ["firstName", "lastName"]

}

JSON validation

http://json-schema.org/

Page 19: Gamers do REST - DjangoCon 2014

{ "title": "Example Schema",

"type": "object",

"properties": {

"name": { "type": "string" },

"gender": {

"type": "string",

"enum": ["male", "female", "other"],

"exceptions": {

"required": errors.GenderMissingError,

"type": errors.InvalidGenderError,

"enum": errors.InvalidGenderError

}

}

},

"required": ["gender"]

}

JSON validation

http://json-schema.org/

Page 20: Gamers do REST - DjangoCon 2014

class ErrorHandlingMiddleware(object):

def process_exception(self, request, exception):

return format_and_render_error(

request,

exception

)

Error handling

Page 21: Gamers do REST - DjangoCon 2014

{ "error": {

"msg": "Request data validation failed, see context for more details.",

"code": 227000,

"name": "Error:ClientError:InvalidRequest:DataInvalid",

"context": [

{

"msg": "Email [email protected] already exists",

"code": 288000,

"name": "Error:ClientError:Conflict:EmailExists"

},

{

"msg": "Username cmac1 already exists",

"code": 289000,

"name": "Error:ClientError:Conflict:UsernameExists"

}

]}}

Error handling

Page 22: Gamers do REST - DjangoCon 2014

Logging

Page 23: Gamers do REST - DjangoCon 2014

Logging

Page 24: Gamers do REST - DjangoCon 2014

Logging// Bad message - not suitable/useful for production.logger.debug(“Variable x={}”.format(var))

// Good message - suitable for production.logger.error(

“Request {request} failed unexpectedly for reason {reason} resulting in client error {error}”

.format({

“request”: req,

“reason”: expl,

“error”: client_error_code})

)

Page 25: Gamers do REST - DjangoCon 2014

Logging

2014-05-10T22:58:56.394565+00:00 level=error project=highlander app=users view=get_UsersView client=127.0.0.1 method=GET path=/v1.0/users/2 msg=Error:NotFound(No user with user_id 2 could be found. There can be only one!)

Page 26: Gamers do REST - DjangoCon 2014

Metrics

Page 27: Gamers do REST - DjangoCon 2014

Metricsclass MetricsMiddleware(object):

def process_request(self, request):

request.metrics_start_time = time.time()

def process_response(self, request, response):

if hasattr(request, 'metrics_start_time'):

time_in_request = (time.time() - request.metrics_start_time) * 1000

metrics.write(

name='request_time',

value=time_in_request

)

return response

Page 28: Gamers do REST - DjangoCon 2014

Auth● We use JSON Web Tokens● JOSE is a framework intended to provide a method to securely transfer

claims:○ https://github.com/Demonware/jose○ https://pypi.python.org/pypi/jose/

or just:% pip install jose

Page 29: Gamers do REST - DjangoCon 2014

Summary

Rest is awesomeBe Pragmatic

Monitor EverythingWe are hiring!!!

Page 30: Gamers do REST - DjangoCon 2014

Questions?


Top Related