Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Django REST Framework における API 実装プラクティス | PyCon JP 2018

11,102 views

Published on

Django REST Framework におけるAPI 実装プラクティス at PyCon JP 2018

Published in: Engineering

Django REST Framework における API 実装プラクティス | PyCon JP 2018

  1. 1. Django REST Framework API Masashi SHIBATA c-bata c_bata_! " PyCon JP 2018 Day1
  2. 2. go-prompt, kube-prompt 
 https://codezine.jp/article/corner/749 c-bata c_bata_! "
  3. 3. Topic 1 PageNumberPagination CursorPagination LimitOffsetPagination CLASS
  4. 4. http://example.com/snippets/?page=4 PageNumberPagination http://example.com/snippets/?limit=5&offset=400 prev: http://example.com/snippets/?cursor=cj0xJnA9MjAxOC next: http://example.com/snippets/?cursor=povlJDFkfhgf0lAj LimitOffsetPagination CursorPagination
  5. 5. http://example.com/snippets/?page=4 PageNumberPagination http://example.com/snippets/?limit=5&offset=400 prev: http://example.com/snippets/?cursor=cj0xJnA9MjAxOC next: http://example.com/snippets/?cursor=povlJDFkfhgf0lAj LimitOffsetPagination CursorPagination per_page
  6. 6. http://example.com/snippets/?page=4 PageNumberPagination http://example.com/snippets/?limit=50&offset=250 prev: http://example.com/snippets/?cursor=cj0xJnA9MjAxOC next: http://example.com/snippets/?cursor=povlJDFkfhgf0lAj LimitOffsetPagination CursorPagination (offset) (limit) page
  7. 7. http://example.com/snippets/?page=4 PageNumberPagination http://example.com/snippets/?limit=50&offset=250 prev: http://example.com/snippets/?cursor=cj0xJnA9MjAxOC next: http://example.com/snippets/?cursor=povlJDFkfhgf0lAj LimitOffsetPagination CursorPagination ID( ) ( )
  8. 8. http://example.com/snippets/?page=4 PageNumberPagination http://example.com/snippets/?limit=50&offset=250 prev: http://example.com/snippets/?cursor=cj0xJnA9MjAxOC next: http://example.com/snippets/?cursor=povlJDFkfhgf0lAj LimitOffsetPagination CursorPagination
  9. 9. http://example.com/snippets/?page=4 PageNumberPagination http://example.com/snippets/?limit=50&offset=250 prev: http://example.com/snippets/?cursor=cj0xJnA9MjAxOC next: http://example.com/snippets/?cursor=povlJDFkfhgf0lAj LimitOffsetPagination CursorPagination (or )
  10. 10. http://example.com/snippets/?page=4 PageNumberPagination http://example.com/snippets/?limit=50&offset=250 prev: http://example.com/snippets/?cursor=cj0xJnA9MjAxOC next: http://example.com/snippets/?cursor=povlJDFkfhgf0lAj LimitOffsetPagination CursorPagination ※ max_id since_id examle.com/snippets?since_id=6
  11. 11. http://example.com/snippets/?page=4 PageNumberPagination http://example.com/snippets/?limit=50&offset=250 prev: http://example.com/snippets/?cursor=cj0xJnA9MjAxOC next: http://example.com/snippets/?cursor=povlJDFkfhgf0lAj LimitOffsetPagination CursorPagination id or
  12. 12. http://example.com/snippets/?page=4 PageNumberPagination http://example.com/snippets/?limit=50&offset=250 prev: http://example.com/snippets/?cursor=cj0xJnA9MjAxOC next: http://example.com/snippets/?cursor=povlJDFkfhgf0lAj LimitOffsetPagination CursorPagination
  13. 13. 1 74 102 85 113 96 12
  14. 14. 1 74 102 85 113 96 12 1 74 102 85 113 96 12
  15. 15. 1 74 102 85 113 96 12 1 74 102 85 113 96 12 id = 3 id=6
  16. 16. 1 74 102 85 113 96 12 1 74 102 85 113 96 12
  17. 17. 1 74 102 85 113 96 121 74 102 85 113 96 12 1 74 102 85 113 96 12 5 1
  18. 18. 1 74 102 85 113 96 12 1 74 102 85 113 96 12
  19. 19. 1 74 102 85 113 96 12 1 74 102 85 113 96 12
  20. 20. id id id id id id id id 3
  21. 21. id id id id id id id id id id id id id id id id
  22. 22. id id id id id id id id id id id id id id id id
  23. 23. id id id id id id id id id id id id id id id id
  24. 24. id id id id id id id id id id id id id id id id
  25. 25.
  26. 26. = SELECT id FROM snippets WHERE is_public = 1 AND created_at > '2018-09-15 08:28:53.312612’ ORDER BY created_at ASC LIMIT 101; ALTER TABLE snippets ADD INDEX ix_created_public(created_at, is_public); SQL Index
  27. 27. INDEX D, J, Z INDEX A, B, D + A 1 INDEX F, H, J B 8 INDEX L, P, Z D 20 INDEX 20, 60, 80 INDEX 1, 8, 20 + 1 c-bata 24 INDEX 21, 50, 60 + 8 denari 23 INDEX 65, 76, 80 + 20 cstoku 25 (InnoDB)
  28. 28. INDEX D, J, Z INDEX A, B, D + A 1 INDEX F, H, J B 8 INDEX L, P, Z D 20 INDEX 20, 60, 80 INDEX 1, 8, 20 + 1 c-bata 24 INDEX 21, 50, 60 + 8 denari 23 INDEX 65, 76, 80 + 20 cstoku 25 (InnoDB)
  29. 29. INDEX D, J, Z INDEX A, B, D + A 1 INDEX F, H, J B 8 INDEX L, P, Z D 20 INDEX 20, 60, 80 INDEX 1, 8, 20 + 1 c-bata 24 INDEX 21, 50, 60 + 8 denari 23 INDEX 65, 76, 80 + 20 cstoku 25 (InnoDB) INDEX
  30. 30. INDEX D, J, Z INDEX A, B, D + A 1 INDEX F, H, J B 8 INDEX L, P, Z D 20 INDEX 20, 60, 80 INDEX 1, 8, 20 + 1 c-bata 24 INDEX 21, 50, 60 + 8 denari 23 INDEX 65, 76, 80 + 20 cstoku 25 (InnoDB)
  31. 31. INDEX D, J, Z INDEX A, B, D + A 1 INDEX F, H, J B 8 INDEX L, P, Z D 20 INDEX 20, 60, 80 INDEX 1, 8, 20 + 1 c-bata 24 INDEX 21, 50, 60 + 8 denari 23 INDEX 65, 76, 80 + 20 cstoku 25 (InnoDB) OFFSET
  32. 32. INDEX D, J, Z INDEX A, B, D + A 1 INDEX F, H, J B 8 INDEX L, P, Z D 20 INDEX 20, 60, 80 INDEX 1, 8, 20 + 1 c-bata 24 INDEX 21, 50, 60 + 8 denari 23 INDEX 65, 76, 80 + 20 cstoku 25 (InnoDB)
  33. 33. SELECT id FROM snippets WHERE is_public = 1 AND created_at > '2018-09-15 08:28:53.312612’ ORDER BY created_at ASC LIMIT 101; ALTER TABLE snippets ADD INDEX ix_created_public(created_at, is_public); SQL Index
  34. 34. SELECT id FROM snippets WHERE is_public = 1 AND created_at > '2018-09-15 08:28:53.312612’ ORDER BY created_at ASC LIMIT 101; ALTER TABLE snippets ADD INDEX ix_created_public(created_at, is_public); SQL Index id, is_public, created_at
  35. 35. SELECT id FROM snippets WHERE is_public = 1 AND created_at > '2018-09-15 08:28:53.312612’ ORDER BY created_at ASC LIMIT 101; ALTER TABLE snippets ADD INDEX ix_created_public(created_at, is_public); SQL Index id, is_public, created_at
  36. 36. SELECT id FROM snippets WHERE is_public = 1 AND created_at > '2018-09-15 08:28:53.312612’ ORDER BY created_at ASC LIMIT 101; ALTER TABLE snippets ADD INDEX ix_created_public(created_at, is_public); SQL Index id, is_public, created_at created_at is_public
  37. 37. Topic 2 AnonRateThrottle ScopedRateThrottle UserRateThrottle KEYWORDS
  38. 38. • • CDN (akamai, fastly, cloudflare, …) • (Nginx, apache, …) • Django • AnonRateThrottle • UserRateThrottle • ScopedRateThrottle
  39. 39. • CDN Rate Limiting, DDoS Protection • https://docs.fastly.com/api/ • https://developer.akamai.com/blog/2018/05/30/ demystifying-api-rate-limiting • • https://www.nginx.com/blog/rate-limiting-nginx/
  40. 40. • AnonRateThrottle: • IP (X-Forwarded-For WSGI environ REMOTE_ADDR ) • UserRateThrottle: • • ScopedRateThrottle: •
  41. 41. • AnonRateThrottle: • IP (X-Forwarded-For WSGI environ REMOTE_ADDR ) • UserRateThrottle: • • ScopedRateThrottle: • CDN Nginx
  42. 42. • AnonRateThrottle: • IP (X-Forwarded-For WSGI environ REMOTE_ADDR ) • UserRateThrottle: • • ScopedRateThrottle: • Github
  43. 43. REST_FRAMEWORK = { 'DEFAULT_THROTTLE_CLASSES': ( ‘rest_framework.throttling.AnonRateThrottle', ‘rest_framework.throttling.UserRateThrottle', ), 'DEFAULT_THROTTLE_RATES': { 'anon': ‘10/min', 'user': ‘100/min' } }
  44. 44. REST_FRAMEWORK = { 'DEFAULT_THROTTLE_CLASSES': ( ‘rest_framework.throttling.AnonRateThrottle', ‘rest_framework.throttling.UserRateThrottle', ), 'DEFAULT_THROTTLE_RATES': { 'anon': ‘10/min', 'user': ‘100/min' } } sec, min, hour, day 1 s m, h, d
  45. 45. REST_FRAMEWORK = { 'DEFAULT_THROTTLE_CLASSES': ( ‘rest_framework.throttling.AnonRateThrottle', ‘rest_framework.throttling.UserRateThrottle', ), 'DEFAULT_THROTTLE_RATES': { 'anon': ‘10/min', 'user': ‘100/min' } } Django LocalMemCache
  46. 46. REST_FRAMEWORK = { 'DEFAULT_THROTTLE_CLASSES': ( ‘rest_framework.throttling.AnonRateThrottle', ‘rest_framework.throttling.UserRateThrottle', ), 'DEFAULT_THROTTLE_RATES': { 'anon': ‘10/min', 'user': ‘100/min' } } Github RateThrottle
  47. 47. https://github.com/c-bata/django-api-practices • • clients/dos.py : 10 • clients/throttle_client.py : • • RATE_LIMIT=true • anon: 3req/s , user: 10req/s
  48. 48. • • clients/dos.py : 10 • clients/throttle_client.py : • • RATE_LIMIT=true • anon: 3req/s , user: 10req/s https://github.com/c-bata/django-api-practices TokenBucketAlgorithm Python 2 14
  49. 49. • CDN Nginx • REST Framework 3 • UserRateLimit • Rate Limit 

  50. 50. Topic 3 TokenAuthentication JWT TokenAuthentication djangorestframework-jwt CLASS
  51. 51. • TokenAuthentication: • djangorestframework-jwt: JSON Web Token • https://github.com/GetBlimp/django-rest-framework-jwt • Refresh JWT
  52. 52. JWT JSON Web Token Claim JSON ( RFC7519)
  53. 53. https://jwt.io
  54. 54. https://jwt.io {header}.{payload}.{signature} header claims urlsafe base64 encode
  55. 55. https://jwt.io ( JWT)
  56. 56. https://jwt.io payload urlsafe base64 decode
  57. 57. RS HS • HMAC: ) HS256 • • • • : ) RS256. PS ES • •
  58. 58. RS HS • HMAC: ) HS256 • • • • : ) RS256 • • HMAC
  59. 59. RS HS • HMAC: ) HS256 • • • • : ) RS256 • • djangorestframework-jwt HS256
  60. 60. RS HS • HMAC: ) HS256 • • • • : ) RS256 • • ) Firebase JWT
  61. 61. RS HS • HMAC: ) HS256 • • • • : ) RS256 • • https://pyjwt.readthedocs.io/en/latest/algorithms.html PyJWT
  62. 62. • TokenAuthentication • djangorestframework-jwt • JWT • JWT • HMAC •
  63. 63. Topic 4 HATEOAS Versioning Specifying media type KEYWORDS
  64. 64. • HATEOAS (Hypertext As The Engine Of Application State) • • • API Django REST Framework
  65. 65. HATEOAS Hypertext As The Engine Of Application State URI 
 API DefaultRouter HyperLinkedModelSerializer $ curl http://localhost:8000/api/ | jq . { "snippets": "http://localhost:8000/api/snippets/" "users": “http://localhost:8000/api/users/“ }
  66. 66. 
 • rest_framework.urlpatterns.format_suffix_patterns
  67. 67. 
 • rest_framework.urlpatterns.format_suffix_patterns $ curl -H 'Accept: text/html' <your api endpoint> BrowsableAPIRenderer
  68. 68. $ curl -u user:pass -d '{}' > http://127.0.0.1:8000/api/snippets/ | jq . { "title": [ " " ], "created_by": [ " " ] }
  69. 69. example.com/v1.0/snippets example.com/snippets?v=2.0 v1.example.com/snippets Accept: application/json; version=3.0
  70. 70. • • • JWT •
  71. 71. THANK YOU

×