Upgrade to Pro — share decks privately, control downloads, hide ads and more …

The Basics of REST With Spring

baeldung
September 16, 2015

The Basics of REST With Spring

A deep dive into the basics of the RESTful Architecture, design principles and the HTTP Semantics of an API With Spring.

The full "REST With Spring" course: www.restwithspring.com

baeldung

September 16, 2015
Tweet

More Decks by baeldung

Other Decks in Programming

Transcript

  1. . . . . . . . . . .

    . . . . REST With Spring HI • My name is Eugen Paraschiv (don’t try to pronounce it) • Created my first REST API with Spring in 2010 • Got excited and started obsessing about REST • Created about 100 separate APIs since then • Made a lot of mistakes and slowly learned from them • The last APIs I created for a client is well positioned to become the largest ElasticSearch installation in the world
  2. . . . . . . . . . .

    . . . . REST With Spring • Help you build a solid, production ready RESTful API with Spring (and Spring Boot) PRESENTATION GOAL
  3. . . . . . . . . . .

    . . . . REST With Spring • What makes a good API AGENDA
  4. . . . . . . . . . .

    . . . . REST With Spring • What makes a good API • Basics of HTTP with REST AGENDA
  5. . . . . . . . . . .

    . . . . REST With Spring • What makes a good API • Basics of HTTP with REST • HTTP Verbs, URLs and Status Codes AGENDA
  6. . . . . . . . . . .

    . . . . REST With Spring • What makes a good API • Basics of HTTP with REST • HTTP Verbs, URLs and Status Codes • Focus on API Errors AGENDA
  7. . . . . . . . . . .

    . . . . QUESTION FOR YOU HAVE YOU IMPLEMENTED A REST API BEFORE?
  8. . . . . . . . . . .

    . . . . REST With Spring • We’re only working with Resources URL – NOUNS, NO VERBS?
  9. . . . . . . . . . .

    . . . . REST With Spring • We’re only working with Resources • Operations on Resources are expressed via HTTP Verbs URL – NOUNS, NO VERBS?
  10. . . . . . . . . . .

    . . . . REST With Spring • We’re only working with Resources • Operations on Resources are expressed via HTTP Verbs • A Verb in the URL is a sign of bad design URL – NOUNS, NO VERBS?
  11. . . . . . . . . . .

    . . . . REST With Spring • Bad: /account/pay URL – NO VERBS – EXAMPLE
  12. . . . . . . . . . .

    . . . . REST With Spring • Bad: /account/pay • Good: /account/payment URL – NO VERBS – EXAMPLE
  13. . . . . . . . . . .

    . . . . REST With Spring • The Resource - is the actual object RESOURCE VS REPRESENTATION
  14. . . . . . . . . . .

    . . . . REST With Spring • The Resource - is the actual object • The Representation - is the object serialized (+ metadata) RESOURCE VS REPRESENTATION
  15. . . . . . . . . . .

    . . . . PAUSE BREETHE ASK QUESTIONS
  16. . . . . . . . . . .

    . . . . REST With Spring • Resource Name: Foo • Base URL: /api/foos • Standard Operations: create, update, delete, get one, get all, get paginated • Constraints: Foos are unique by name EXAMPLE API
  17. . . . . . . . . . .

    . . . . A CREATE OPERATION
  18. . . . . . . . . . .

    . . . . REST With Spring • HTTP Verb: POST • URL: /foos – plural • Response: 201 Created CREATE @RequestMapping(value = "/foos", method = POST) @ResponseStatus(HttpStatus.CREATED) public void create(@Valid @RequestBody Foo resource) { service.create(resource); }
  19. . . . . . . . . . .

    . . . . REST With Spring • Both designs are OK, neither is wrong URL – SINGULAR VS PLURAL
  20. . . . . . . . . . .

    . . . . REST With Spring • Both designs are OK, neither is wrong • Plural indicates that we’re working with a Collections Resource – When we GET, we get back the entire collection URL – SINGULAR VS PLURAL
  21. . . . . . . . . . .

    . . . . REST With Spring • Both designs are OK, neither is wrong • Plural indicates that we’re working with a Collections Resource – When we GET, we get back the entire collection – When we POST, we append / add a new Resource into the collection URL – SINGULAR VS PLURAL
  22. . . . . . . . . . .

    . . . . REST With Spring • Both designs are OK, neither is wrong • Plural indicates that we’re working with a Collections Resource – When we GET, we get back the entire collection – When we POST, we append / add a new Resource into the collection – When we want a single Resource -> we drill into the Collection with a further unique identifier URL – SINGULAR VS PLURAL
  23. . . . . . . . . . .

    . . . . AN UPDATE OPERATION
  24. . . . . . . . . . .

    . . . . REST With Spring • HTTP Verb: PUT • URL: /foos/1 – plural + {id} • Response: 200 OK UPDATE @RequestMapping(value = "/foos/{id}", method = PUT) @ResponseStatus(HttpStatus.OK) public void create( @PathVariable("id") Long id, @Valid @RequestBody Foo resource) { service.update(resource); }
  25. . . . . . . . . . .

    . . . . REST With Spring • A HTTP concern, not a REST concern CREATE VS UPDATE – POST VS PUT
  26. . . . . . . . . . .

    . . . . REST With Spring • A HTTP concern, not a REST concern • PUT is idempotent, POST is not CREATE VS UPDATE – POST VS PUT
  27. . . . . . . . . . .

    . . . . REST With Spring • A HTTP concern, not a REST concern • PUT is idempotent, POST is not • PUT is closer to the semantic of replace • POST is closer to the semantic of insert CREATE VS UPDATE – POST VS PUT
  28. . . . . . . . . . .

    . . . . REST With Spring • => We are going to use: – POST for create (subordinate Resources) – PUT for full update (replace) CREATE VS UPDATE – POST VS PUT
  29. . . . . . . . . . .

    . . . . REST With Spring • PUT has full update (replace) semantics WHAT ABOUT PARTIAL UPDATES?
  30. . . . . . . . . . .

    . . . . REST With Spring • PUT has full update (replace) semantics • What about partial updates? WHAT ABOUT PARTIAL UPDATES?
  31. . . . . . . . . . .

    . . . . REST With Spring • PUT has full update (replace) semantics • What about partial updates? • Use PATCH! WHAT ABOUT PARTIAL UPDATES?
  32. . . . . . . . . . .

    . . . . A DELETE OPERATION
  33. . . . . . . . . . .

    . . . . REST With Spring • HTTP Verb: DELETE • URL: /foos/1 – plural + {id} • Response: 204 No Content DELETE @RequestMapping(value = "/foos/{id}", method = DELETE) @ResponseStatus(HttpStatus.OK) public void create(@PathVariable("id") Long id) { service.delete(id); }
  34. . . . . . . . . . .

    . . . . REST With Spring • The HTTP Spec says that DELETE is idempotent; but: – We send the first DELETE to a Resource – it gets deleted – We send a second DELETE to the same Resource - 404 IS DELETE IDEMPOTENT?
  35. . . . . . . . . . .

    . . . . REST With Spring • The HTTP Spec says that DELETE is idempotent; but: – We send the first DELETE to a Resource – it gets deleted – We send a second DELETE to the same Resource - 404 • Idempotence refers to the state of the system after the request has completed IS DELETE IDEMPOTENT?
  36. . . . . . . . . . .

    . . . . GET OPERATIONS
  37. . . . . . . . . . .

    . . . . REST With Spring • HTTP Verb: GET (of course) • URL: /foos/1 – plural + {id} • Response: 200 OK GET ONE @RequestMapping(value = "/foos/{id}", method = GET) @ResponseBody public Foo findById(@PathVariable("id") Long id) { return service.findOne(id); }
  38. . . . . . . . . . .

    . . . . REST With Spring • HTTP Verb: GET (of course) • URL: /foos – plural • Response: 200 OK GET ALL @RequestMapping(value = "/foos", method = GET) @ResponseBody public List<Foo> findAll() { return service.findAll(); }
  39. . . . . . . . . . .

    . . . . A “GET ALL PAGINATED” OPERATION
  40. . . . . . . . . . .

    . . . . REST With Spring • HTTP Verb: GET • URL: /foos?page=1&size=5 • Response: 200 OK GET ALL - PAGINATED @RequestMapping( value = "/foos", params = { "page", "size" }, method = RequestMethod.GET) @ResponseBody public List<Foo> findPaginated( @RequestParam("page") int page, @RequestParam("size") int size) { return service.findPaginated(page, size).getContent(); }
  41. . . . . . . . . . .

    . . . . REST With Spring GET ALL – PAGINATED - EXAMPLE GET http://localhost:8080/api/foos?page=1&size=10 Link= <http://localhost:8080/api/foos?page=0&size=10>; rel="first", <http://localhost:8080/api/foos?page=78&size=10>; rel="last", <http://localhost:8080/api/foos?page=6&size=10>; rel="next", <http://localhost:8080/api/foos?page=4&size=10>; rel="prev"
  42. . . . . . . . . . .

    . . . . PAUSE BREETHE ASK QUESTIONS
  43. . . . . . . . . . .

    . . . . PROBLEMS, ERRORS, EXCEPTIONS
  44. . . . . . . . . . .

    . . . . REST With Spring • 400 Bad Request • 401 Unauthenticated and 403 Forbidden • 404 Not Found • 405 Method Not Allowed • 409 Conflict • 415 Unsupported Media Type CLIENT ERRORS – 4XX
  45. . . . . . . . . . .

    . . . . REST With Spring • The generic, catch-all for client side errors • Usually happens for PUT or POST requests • Usually means that the Representation of the Resource is in the right format but still doesn’t make sense 400 Bad Request
  46. . . . . . . . . . .

    . . . . REST With Spring • Should have been named 401 Unauthenticated • The Client is trying to operate on a protected Resource without providing the proper authentication credentials 401 Unauthorized
  47. . . . . . . . . . .

    . . . . REST With Spring • The Client is trying to work with a protected Resource, has provided correct authentication credentials, but simply does not have enough access to that Resource 403 Forbidden
  48. . . . . . . . . . .

    . . . . REST With Spring • The Client tries to operate on a Resource that does not exist • 410 Gone – similar, but better semantics 404 Not Found
  49. . . . . . . . . . .

    . . . . REST With Spring • The Method specified in the client request is not allowed for that Resource • The response should contain an Allow header 405 Method Not Allowed
  50. . . . . . . . . . .

    . . . . REST With Spring • The request could not be completed due to a conflict with the current state of the resource • Ex: We try to create a Foo Resource with the same name as an existing one => 409 • Do NOT use 412 Precondition Failed instead! 409 Conflict
  51. . . . . . . . . . .

    . . . . REST With Spring • The Representation provided by the Client is not supported • Example: The API only supports JSON • Content-Type: application/xml 415 Unsupported Media Type
  52. . . . . . . . . . .

    . . . . LESS COMMON 4XX STATUS CODES
  53. . . . . . . . . . .

    . . . . REST With Spring • 411 Length Required OTHER 4XX STATUS CODES
  54. . . . . . . . . . .

    . . . . REST With Spring • 411 Length Required • 413 Request Entity Too Large • 414 Request URI Too Long OTHER 4XX STATUS CODES
  55. . . . . . . . . . .

    . . . . REST With Spring • Use @ControllerAdvice to do global error handling SPRING GLOBAL EXCEPTION HANDLING
  56. . . . . . . . . . .

    . . . . REST With Spring • Use @ControllerAdvice to do global error handling • It can handle exceptions individually or together SPRING GLOBAL EXCEPTION HANDLING
  57. . . . . . . . . . .

    . . . . REST With Spring • Use @ControllerAdvice to do global error handling • It can handle exceptions individually or together • And It allows full control over the body of the Response SPRING GLOBAL EXCEPTION HANDLING
  58. . . . . . . . . . .

    . . . . REST With Spring HANDLE A SINGLE EXCEPTION @ExceptionHandler({ InvalidDateException.class }) public ResponseEntity<Object> handleInvalidDate( InvalidDateException ex, WebRequest request) { … }
  59. . . . . . . . . . .

    . . . . REST With Spring HANDLE TWO EXCEPTIONS @ExceptionHandler({ InvalidDateException.class, IllegalArgumentException.class }) public ResponseEntity<Object> handleInvalidDate( RuntimeException ex, WebRequest request) { … }
  60. . . . . . . . . . .

    . . . . REST With Spring THE ERROR RESPONSE BODY @ExceptionHandler({ … }) public ResponseEntity<Object> handleInvalidDate( RuntimeException ex, WebRequest request) { … return handleExceptionInternal( ex, new ApiError(…), new HttpHeaders(), BAD_REQUEST, request); }
  61. . . . . . . . . . .

    . . . . REST With Spring ERROR HANDLING ON THE CLIENT HTTP/1.1 400 Bad Request Content-Type: application/json;charset=UTF-8 ... { "ui-error": "There was a validation problem", "dev-error": "MethodArgumentNotValidException", "fieldErrors": [ { "field": "data[0].name", "message": "may not be null" } ] }
  62. . . . . . . . . . .

    . . . . REST With Spring • The basics of REST terminology - Resource vs. Representation • Good URL practices: Nouns vs. Verbs, Plural vs. Singular • Create vs. Update - POST vs PUT (vs PATCH) • Is Delete Idempotent? • How to implement pagination in the API well • Deep dive into the 4xx class of Client Errors • Spring - Exception Handling WHAT WE LEARNED
  63. LIVE TRAINING The Starter Class – 3 courses - went

    live on the 1st of October Course 1 - The Basics of REST with Spring (60 minutes) Course 2 - REST and HTTP Semantics (72 minutes) Course 3 - Simple Security for REST (40 minutes) REST With Spring http://restwithspring.com
  64. LIVE TRAINING The Intermediate Class – 6 courses - went

    live on the 10th of November Course 4 - Consuming the API from AngularJS (42 minutes) Course 5 - Testing the API (56 minutes) Course 6 - Advanced Security: OAuth2 and JWT (48 minutes) REST With Spring http://restwithspring.com
  65. LIVE TRAINING The Master Class – the full 9 courses

    - goes live on the 20th of December Course 7 - Document, Discover and Evolve the REST API Course 8 – Monitoring and Metrics of REST API Course 9 - CI and CD Pipelines for the API REST With Spring http://restwithspring.com
  66. LIVE TRAINING The Starter Class – 3 courses – 49$

    - went live on the 1st of October The Intermediate Class – 6 courses – 99$ 74$ - went live on the 10th of November The Master Class – 9 courses – 149$ 112$ - out on the 20th of December REST With Spring http://restwithspring.com
  67. . . . . . . . . . .

    . . . . ANNOUNCING A NEW LIVE WORKSHOP February 10th
  68. LIVE TRAINING “Advanced API Security” Workshop • How to set

    up OAuth2 for a public API • JSON Web Tokens (JWT) • Token storage on the front-end (AngularJS)
  69. LIVE TRAINING “Advanced API Security” Workshop • How to do

    a proxy-server implementation • CSRF protection in-depth • A full project template for the implementation
  70. LIVE TRAINING Webinar Bonus (next 24 hours) The Advanced API

    Security Live Workshop – 67$ With the Master Class of REST With Spring – 10 free seats 10th of February 2016
  71. . . . . . . . . . .

    . . . . THANK YOU It’s Q&A Time