There is no “one and only” way; each team has to choose the most suitable approach for their situation and project. What is common throughout all the teams is the need to make choices. In this talk we will look at the choices we’ve faced in our team, what options did we consider and what conclusions did we come to.
Video: https://www.youtube.com/watch?v=5ZDuvAwSmeA
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
The one and only way of designing Java applications
1. The one and only way
of designing Java
applications
Arturs Drozdovs (@Mordavolt)
2. Outline
●
API: REST vs RPC
●
Packages: Domain vs Functionality
●
Exceptions: Checked vs Runtime
●
Tests: Unit vs Functional
●
Frameworks and Libraries
3. API: REST vs RPC
●
REST
– Uses HTTP verbs as actions
– Can be traversed and manipulated intuitively (HATEOAS)
●
RPC
– Uses URIs as actions
– Has to be premediated
5. Create
POST /orders
{
"amount": 100
}
> 201 Created
> Location: orders/123
PUT /orders/123
{
"id": 123,
"amount": 100
}
> 200 OK | 204 No Content
POST /orders/create
POST /orders/add
POST /orders?action=create
POST /orders
{
"amount": 100
}
> ????
□ REST □ RPC
6. Read
GET /orders
>200 OK
>[
> {
> "id": 123,
> "amount": 100
> }
>]
GET /orders?amount=101
>200 OK
>[]
□ REST and RPC
GET /orders/123
>200 OK
>{
> "id": 123,
> "amount": 100
>}
GET /orders/555
>404 Not Found
7. Update
PUT /orders/123
{
"id": 123,
"amount": 777
}
> 200 OK | 204 No Content
PATCH /orders/123
Content-Type: application/json-patch+json
[
{ "op": "replace", "path": "/amount",
"value": 777 }
]
> 200 OK | 204 No Content
POST /orders/123/update
POST /orders/update?id=123
POST /orders?
action=update&id=123
POST /orders
{
"amount": 777
}
> ????
□ REST □ RPC
8. Delete
DELETE /orders/123
> 200 OK | 202 Accepted
| 204 No Content
GET /orders/123/delete
GET /orders/123?action=delete
POST /orders/123?action=delete
> ????
□ REST □ RPC
13. Why package-private is cool?
●
Less coupling
●
Clean global scope
●
No service bypass
●
No mindless reuse
●
Easy to search for
related items
14. Exceptions: Checked vs Runtime
class SomeClass {
class CheckedException extends Exception {}
class UncheckedException extends RuntimeException {}
void fail() { throw new CheckedException(); }
void failSilently() { throw new UncheckedException(); }
}
All business logic exceptions should be checked!
15. 2 rules of domain abstractions
Get Data
Some Data
No Data
Failure
ServiceA
ServiceB
GetA
GetB FailB
FailB
17. Example Exception Usage
public Order getOrder(int id) throws OrderNotFoundException {
//return new Order();
throw new OrderNotFoundException("Order not found");
}
void doStuffWithOrder(int id) {
try {
service.getOrder(id);
} catch (OrderException e) {
e.printStackTrace();
}
}
18. Why does it fail? :(
●
Have to try-catch
●
Can’t throw another exception
●
No fail flow
19. What do?
●
Don’t use checked exceptions
●
Wrap with runtime exceptions
●
Use RxJava or Reactor
20. Tests: Unit vs Functional
●
Unit tests
– Test smallest possible unit of code
– Highly code dependant
– Quick
●
Functional tests
– Test all parts in conjunction
– API dependant
– Slow and inefficient