Леонід Кузьмін “Сам собі паблішер. Від сайту ігрової студії до універсального back-end провайдера і сервісу публікації ігор.”
http://gamedev.lviv.ua
https://www.facebook.com/startuplviv
https://twitter.com/gdlviv
Value Proposition canvas- Customer needs and pains
Леонід Кузьмін “Сам собі паблішер. Від сайту ігрової студії до універсального back-end провайдера і сервісу публікації ігор.”
1. Сам собі паблішер. Від сайту ігрової студії до
універсального back-end провайдера і сервісу
публікації ігор.
Leonid Kuzmin
EFORB GAMEBOX
2.
3.
4.
5. REST and RESTful API
RESTful API adhere to the REST architectural constraints.
REST is not a protocol, but architectural style
6. • Client-Server – determined by environment
REST Architectural Constraints
applied to web services
REST and
RESTful API
7. • Client-Server – determined by environment
• Stateless – data needed for authentication included in every request
headers (e.g. Cookies)
REST Architectural Constraints
applied to web services
REST and
RESTful API
8. • Client-Server – determined by environment
• Stateless – data needed for authentication included in every request
headers (e.g. Cookies)
• Cacheable – HTTP cache control headers
REST Architectural Constraints
applied to web services
REST and
RESTful API
9. • Client-Server – determined by environment
• Stateless – data needed for authentication included in every request
headers (e.g. Cookies)
• Cacheable – HTTP cache control headers
• Layered system – reverse proxy server could be used
REST Architectural Constraints
applied to web services
REST and
RESTful API
10. • Client-Server – determined by environment
• Stateless – data needed for authentication included in every request
headers (e.g. Cookies)
• Cacheable – HTTP cache control headers
• Layered system – reverse proxy server could be used
• Uniform interface
REST Architectural Constraints
applied to web services
REST and
RESTful API
11. • Client-Server – determined by environment
• Stateless – data needed for authentication included in every request
headers (e.g. Cookies)
• Cacheable – HTTP cache control headers
• Layered system – reverse proxy server could be used
• Uniform interface
REST Architectural Constraints
applied to web services
- Identification of resources – URI
REST and
RESTful API
12. • Client-Server – determined by environment
• Stateless – data needed for authentication included in every request
headers (e.g. Cookies)
• Cacheable – HTTP cache control headers
• Layered system – reverse proxy server could be used
• Uniform interface
REST Architectural Constraints
applied to web services
- Identification of resources – URI
- Self-descriptive messages – HTTP headers: cache
control headers, “Content-Type” header, “Accept” header
REST and
RESTful API
13. • Client-Server – determined by environment
• Stateless – data needed for authentication included in every request
headers (e.g. Cookies)
• Cacheable – HTTP cache control headers
• Layered system – reverse proxy server could be used
• Uniform interface
REST Architectural Constraints
applied to web services
- Identification of resources – URI
- Self-descriptive messages – HTTP headers: cache
control headers, “Content-Type” header, “Accept” header
- Standard HTTP methods: POST, GET, PUT, DELETE and HTTP
Response codes
REST and
RESTful API
14. • Client-Server – determined by environment
• Stateless – data needed for authentication included in every request
headers (e.g. Cookies)
• Cacheable – HTTP cache control headers
• Layered system – reverse proxy server could be used
• Uniform interface
REST Architectural Constraints
applied to web services
- Identification of resources – URI
- Self-descriptive messages – HTTP headers: cache
control headers, “Content-Type” header, “Accept” header
- Standard HTTP methods: POST, GET, PUT, DELETE and HTTP
Response codes
- Resource entities can be filtered by referencing resources
properties values in URI REST and
RESTful API
15. This is not RESTful
POST /createAccount
Request:
Cookie: ...
{name: Petro, email: president@gov.ua}
Response:
{name: Petro, email: president@gov.ua}
GET /getAllAccounts?name=Petro
Request:
Cookie: ...
Response:
[{name: Petro, email: president@gov.ua},
{name: admin, email: admin@gov.ua}]
GET /findAccounts?name=Petro
Request:
Cookie: ...
Response:
[{name: Petro, email: president@gov.ua}]
GET /getAccount?id=1
Request:
Cookie: ...
Response:
{name: Petro, email: president@gov.ua}
POST /updateAccount
Request:
Cookie: ...
{id: 1, name: PetroP, email: president@gov.ua}
Response:
{name: PetroP, email: president@gov.ua}
POST /deleteAccount
Request:
Cookie: ...
{id: 1}
Response codes
Success: 200 OK
Fail: 200 OK {error: …}
18. Calculated data in REST
Int sum (a, b)
{ return a + b; }
• GET /sum – collection of all integers' sums: [0, 1, 2, 3, ..., N, ...]
• GET /sum/N – collection of all sums of 2 and all integers: [2, 3, 4, ..., N, ...]
• GET/sum/N/M–N+M
• POST /account/1/leaderboard/2 {score: 50}
• GET /account/1/leaderboard/2 {score: 100}
• GET /leaderboard/2 [ { account_id: 1, score: 100, position: 2 },
{ account_id: 2, score: 200, position: 1 }
Game Leaderboard [
{ account_id: 1, score: 50, game_id: 2 },
{ account_id: 1, score: 100, game_id: 2 },
{ account_id: 2, score: 150, game_id: 2 },
{ account_id: 2, score: 200, game_id: 2 }]
19. RESTful: Pros and Cons
PROS
• Simply
• Consistent
• Easy to debug
• Scalable
20. RESTful: Pros and Cons
PROS CONS
• Simply
• Consistent
• Easy to debug
• Scalable
• Strange
• Lack of support
• Stateless
• Not a protocol
21. What we got from REST
• Direct mapping of resources to DB entities (SQL tables, NoSQL documents
collections): POST /accounts => INSERT INTO accounts
22. What we got from REST
• Direct mapping of resources to DB entities (SQL tables, NoSQL documents
collections): POST /accounts => INSERT INTO accounts
• Same access policies for different authentication flows (Cookies authorization,
HTTP basic authorization)
23. What we got from REST
• Direct mapping of resources to DB entities (SQL tables, NoSQL documents
collections): POST /accounts => INSERT INTO accounts
• Same access policies for different authentication flows (Cookies authorization,
HTTP basic authorization)
• URI aliases (/accounts/1 => / me, /account/1/gamedata =>/my/gamedata)
24. What we got from REST
• Direct mapping of resources to DB entities (SQL tables, NoSQL documents
collections): POST /accounts => INSERT INTO accounts
• Same access policies for different authentication flows (Cookies authorization,
HTTP basic authorization)
• URI aliases (/accounts/1 => / me, /account/1/gamedata =>/my/gamedata)
• Common design guidelines
25. What we got from REST
• Direct mapping of resources to DB entities (SQL tables, NoSQL documents
collections): POST /accounts => INSERT INTO accounts
• Same access policies for different authentication flows (Cookies authorization,
HTTP basic authorization)
• URI aliases (/accounts/1 => / me, /account/1/gamedata => / my/gamedata)
• Common design guidelines
• Same back-end for external and internal
services
26. What we got from REST
• Direct mapping of resources to DB entities (SQL tables, NoSQL documents
collections): POST /accounts => INSERT INTO accounts
• Same access policies for different authentication flows (Cookies authorization,
HTTP basic authorization)
• URI aliases (/accounts/1 => / me, /account/1/gamedata => / my/gamedata)
• Common design guidelines
• Same back-end for external and internal
services
• Common test flow
27. REST API Testing
Test Unit = HTTP Verb + URI + Request headers + [Request Body]
HTTP Verb
URL
Request headers + [Request Body]
Test steps
1. Start the Application
2. Prepare test data in storage if needed
3. Perform HTTP API query
4. Check response headers and body
5. Check affected piece of data retrieved from storage directly or even through the REST API
Storage API could be stubbed and spied, in this case storage API calls should be checked
on step 5.
29. Our API Building Codex
1. Everything is a collection
2. Every collection has CRUD (POST, GET, PUT, DELETE)
30. Our API Building Codex
1. Everything is a collection
2. Every collection has CRUD (POST, GET, PUT, DELETE)
3. Use HTTP response codes
31. Our API Building Codex
1. Everything is a collection
2. Every collection has CRUD (POST, GET, PUT, DELETE)
3. Use HTTP response codes
4. Filter and pagination through URI params
32. Our API Building Codex
1. Everything is a collection
2. Every collection has CRUD (POST, GET, PUT, DELETE)
3. Use HTTP response codes
4. Filter and pagination through URI params
5. API version in URI
33. Our API Building Codex
1. Everything is a collection
2. Every collection has CRUD (POST, GET, PUT, DELETE)
3. Use HTTP response codes
4. Filter and pagination through URI params
5. API version in URI
6. Communicate with developers
34. Our API Building Codex
1. Everything is a collection
2. Every collection has CRUD (POST, GET, PUT, DELETE)
3. Use HTTP response codes
4. Filter and pagination through URI params
5. API version in URI
6. Communicate with developers
7. Documentation in code and tests
35. Our API Building Codex
1. Everything is a collection
2. Every collection has CRUD (POST, GET, PUT, DELETE)
3. Use HTTP response codes
4. Filter and pagination through URI params
5. API version in URI
6. Communicate with developers
7. Documentation in code and tests
8. No exceptions
36. Our API Building Codex
1. Everything is a collection
2. Every collection has CRUD (POST, GET, PUT, DELETE)
3. Use HTTP response codes
4. Filter and pagination through URI params
5. API version in URI
6. Communicate with developers
7. Documentation in code and tests
8. No exceptions
9. No exceptions for “No exceptions”
37. How games are published
Traditional Way Our Way
• Sign contract
• Satisfy publisher requirements
• Deploy game somewhere and provide
link to publisher or send game archive
directly
• Receive profit according to contract
• Register, fill billing info
• Fill game description fields, upload
game archive through API
• Game appears in available games
list for clients
• Start earning from ads and transactions
38. Our publishing way vs traditional way
Increased time between complete game and
actual publishing
Almost immediate game publishing
You need to implement and maintain back-end
for your games
Back-end services included
You need to implement monetization (ads or
transactions)
Ads are served by our service, payment system
could be integrated with API. You receive profit
share.
Payment reports are often poor Full reports from ad providers and payment
systems
You need to maintain your own deploy cycle We have sandbox mode where you can view
your game before actual publishing.
Deployment API can be
Traditional Way Our Way
39. Embedding to third-party WEB
resources
• IFrame
• Construct application on the fly on page with JS
• Subdomain with third-party wrapper
40. Embedding: IFrame
PROS
• Easy and obvious
• No cross-domain
requests
• Client can control own
page view
• Client can control own
page view
• No conflicts with client's
JS and CSS
41. Embedding: IFrame
PROS CONS
• Easy and obvious
• No cross-domain
requests
• Client can control own
page view
• Client can control own
page view
• No conflicts with client's
JS and CSS
• Client should be explicitly
identified in each AJAX
request
• Client can't customize
our application view
• Third-party cookies
browser policies
• No direct links to our
application's subpages
• Increased page
construction time
42. Embedding: Subdomain
PROS
• No third-party cookies
• Client identified by domain
• No cross-domain requests
• Direct links to our application
subpages
• Less page construction time
• No conflicts with client's JS
and CSS
43. Embedding: Subdomain
PROS CONS
• No third-party cookies
• Client identified by domain
• No cross-domain requests
• Direct links to our application
subpages
• Less page construction time
• No conflicts with client's JS
and CSS
• Server configuration on the
side of Client
• Client can't customize
application view by own
CSS or JS
• Client can't customize own
views in wrapper
44. Embedding: Construct on the fly with JS
PROS
• No third-party cookies
• Client identified by domain
• No cross-domain requests
• Client can customize our
application view
• Client can control own page
• Direct links to our application
subpages
45. Embedding: Construct on the fly with JS
PROS CONS
• No third-party cookies
• Client identified by domain
• No cross-domain requests
• Client can customize our
application view
• Client can control own page
• Direct links to our application
subpages
• Increased page construction
time
• Restricting customization
of our application by Client's
CSS
• Isolating our application from
client's JS
46. Construct on the fly solutions
• Increased page construction time – pre-
rendered HTML
• Restricting customization of our application's
CSS – random dynamic prefix for CSS
CSS
client.css.tpl:
.{{placeholder}}_class {
color: red;
}
GET /client.css
.SOME_RANDOM_VALUE_class {
color: red;
}
JS
app.js.tpl:
function App (cssPrefix) {
var container = document.createElement('div');
container.className = cssPrefix + '_class';
}
new App({{placeholder}});
GET app.js
…
new App(‘SOME_RANDOM_VALUE’);
• Isolating our application from client's JS – wrap all
code in closure, do not touch existing objects
(internal browser objects, DOM objects etc.)
(function () {
//all application code here
})();
var container = document.createElement('div');
container.remove = function () {…}; //wrong
function remove (element) {…} //right
47. Our technologies and tools
• Back-end
• Front-end
- Node.js (Sails.js, pm2, Grunt)
- PostgreSQL
- HTML 5, CSS3
- Require.js
- Google Closure Compiler + Almond.js for production build