[Java] Java๋ก ๊ฐ๋ ฅํ REST API ๊ตฌ์ถ 4๊ฐ์ง ํ
1. Four Essential Tips for Building a Robust REST API in Java
https://dzone.com/articles/four-tips-for-building-a-robust-rest-api-in-java
Four Tips for Building a Robust REST API in Java - DZone
Enhance your Java REST API with consistent resource naming, maintainable versioning, robust security, and proper exception handling.
dzone.com
[ ์์ฝ ]
Java๋ฅผ ์ฌ์ฉํ์ฌ ๊ฐ๋ ฅํ REST API๋ฅผ ๊ฐ๋ฐํ๊ธฐ ์ํ ์ฃผ์ ์ ๋ต์ ์ ๊ณตํ๋ค.
1. ์๋ํฌ์ธํธ๋ฅผ ๋ ผ๋ฆฌ์ ์ผ๋ก ๊ตฌ์กฐํํ๊ธฐ โก๏ธ ์ ์ฉ์ฑ ๋ฐ ์์น ๊ฐ์
์ผ๊ด๋ ์ฉ์ด, ๋ช ๋ช ๊ท์น์ ๊ธฐ๋ฐ์ผ๋ก ๊ตฌํํด์ผ ํ๋ค.
๋๋ฉ์ธ ์ฃผ๋ ์ค๊ณ(DDD) ์์น์ ๋ฐ๋ผ ์ฃผ์ ๋๋ฉ์ธ์ผ๋ก ์์ํ์ฌ ๋ค์ ํ์ ๋๋ฉ์ธ์ผ๋ก ์ธ๋ถํํ๋ค
์๋ฅผ ๋ค์ด,
GET /expeditions - ๋ชจ๋ ๋ฐ์ดํฐ search
GET /expeditions/{id} - ํน์ id๋ฅผ ๊ฐ์ง ๋ฐ์ดํฐ๋ฅผ search
@Path("expeditions")
public class ExpeditionResource {
@GET
public List<Expedition> list() {
// implementation here
}
@GET
@Path("/{id}")
public Expedition get(@PathParam("id") String id) {
// implementation here
}
@GET
@Path("/search")
public List<Expedition> mine() {
// implementation here
}
}
* ๋ ์์ธํ ๊ฑด REST API ์ค๊ณ ๊ท์น์ ์ฐพ์๋ด์ผ ํ๋ค.
2. ์ ์ง ๋ณด์์ฑ โก๏ธ ํ์ฅ์ฑ ๋ฐ ๋ฌธ์ํ๋ฅผ ์ํด
2.1. ํฌ๊ด์ ์ธ API ๋ฌธ์ ์ถ๊ฐ
API๊ฐ ์ฑ์ฅํจ์ ๋ฐ๋ผ ์ ์ง ๋ณด์์ ํ์ฅ ๊ฐ๋ฅ์ฑ์ ํ๋ณดํ๋ ๊ฒ์ ๋งค์ฐ ์ค์ํ๋ค.์ ์ง ๋ณด์์ฑ์ ๋์ด๋ ๋ฐฉ๋ฒ ์ค ํ๋๋ก, ์ ์ ํ ๋ฌธ์ํ๋ฅผ ์ ์ํ๊ณ ์๋ค.๋ง์ ๊ฐ๋ฐ์๋ค์ด API ๋ฌธ์ํ๋ฅผ ์ ํธํ์ง ์์ง๋ง, OpenAPI๋ฅผ ํตํด ๋ฌธ์ ์๋ ์์ฑ ๋ฐ ๊ด๋ฆฌ๋ฅผ ์งํํ ์ ์๋ค.
๋ฌด์๋ณด๋ค ์์ด์๋ ์ ๋ ์ค์ํ ์์ ์ด๊ธฐ๋ ํ๋ค.
2.2.๋ฒ์ ๊ด๋ฆฌ
๋ ๋ค๋ฅธ ํ๋๋ ๋ฒ์ ๊ด๋ฆฌ๋ค. ๋ฒ์ ๊ด๋ฆฌ๋ ์ด์ ๋ฒ์ ๊ณผ์ ํธํ์ฑ์ ์ ์งํ๋ฉฐ, ์ฌ์ฉ์๊ฐ ํธ์์ ๋ฐ๋ผ ์ต์ ๋ฒ์ ์ผ๋ก ๋ง์ด๊ทธ๋ ์ด์ ํ ์ ์๋๋ก ์ง์ํ๋ค.
Java์์ ์ด๋ฅผ ๊ตฌํํ๋ ค๋ฉด ๋ฒ์ ๋ง๋ค ๋ณ๋์ ํจํค์ง๋ฅผ ๊ตฌ์กฐํํ๊ณ , ์ด๋ํฐ ๋ ์ด์ด๋ฅผ ๋ง๋ค์ด ์๋ก ๋ค๋ฅธ ๋ฒ์ ๊ฐ์ ์ํธ์์ฉ์ ๊ด๋ฆฌํ ์ ์๋ค.
package os.expert.demo.expeditions.v1;
@Path("/api/v1/expeditions")
public class ExpeditionResource {
// implementation here
}
package os.expert.demo.expeditions.v2;
@Path("/api/v2/expeditions")
public class ExpeditionResource {
// implementation here
}
์ ์์์ ๊ฐ์ด ๊ฐ ๋ฒ์ ์ ๋ํ ๋ณ๋์ ํด๋์ค ๊ด๋ฆฌ๋ฅผ ํตํด API ์ด์ ๋ฒ์ ๊ณผ ์ ๋ฒ์ ์ ๋์์ ์ฌ์ฉํ ์ ์์ด, ๋ฒ์ ๊ฐ ์ ํ์ด ๋ ์ํํด์ง๋ค.
3. ์ฌ์ฉ์ ๊ฒ์ฆ ๋ก์ง โก๏ธ ๋ฐ์ดํฐ ๋ฌด๊ฒฐ์ฑ ๋ณด์ฅ
๋งจ ์ฒ์ ๋ฒ์ญ ๋๋ ธ์ ๋ "์ฌ์ฉ์๋ฅผ ์ ๋ ๋ฏฟ์ง ๋ง์ธ์" ๋ผ๊ณ ๋์ ๋๋๋ค..ใ
ใ
๋ณด์์ ๋ชจ๋ API์ ๊ธฐ๋ณธ์ ์ธ ์ธก๋ฉด์ผ๋ก์, ์ผ๋ฐ์ ์ผ๋ก ์ฌ์ฉ์๋ฅผ ์ ๋ ์ ๋ขฐํ์ง ๋ง ๊ฒ์ ๊ฐ์กฐํ๋ค.
@GET
@Path("/my-expeditions")
public List<Expedition> myExpeditions() {
// No need to request IDs since the user is authenticated
// implementation here
}
์ฌ์ฉ์๊ฐ ์ ๊ณตํ ID์๋ ์์กดํ๋, ์ ๋ ฅ์ ์ ๋ ์ ๋ขฐํ์ง ๋ง๊ณ ๊ถํ ์ธ์ฆ์ ํ์์ ์ผ๋ก ์งํํด์ผ ํ๋ค.
๊ถํ ๊ฒ์ฌ๋ฅผ ํญ์ ์ํํ์ฌ ๊ถํ์ ๊ฐ๊ณ ์์ง ์์ ์๊ฐ ๋ฌด๋จ์ผ๋ก ์์ ํ๋ ํ์๋ฅผ ๋ง์์ผ ํ๋ค.
4. ์ ์ ํ ์์ธ ์ฒ๋ฆฌ โก๏ธ API ์ผ๊ด์ฑ์ ์ ์ง
์ ์ค๊ณ๋ API๋ ์ ์ ํ HTTP ์ํ ์ฝ๋์ ๋งคํํ๋ ๊ฐ๋ ฅํ ์์ธ ์ฒ๋ฆฌ ๊ธฐ๋ฅ์ ๊ฐ์ถ์ด์ผ ํ๋ค.
@Provider
public class ExpeditionNotFoundExceptionMapper implements ExceptionMapper<ExpeditionNotFoundException> {
@Override
public Response toResponse(ExpeditionNotFoundException exception) {
return Response.status(Response.Status.NOT_FOUND).entity(exception.getMessage()).build();
}
}
์ ์์์ ๊ฐ์ด, ์ฌ์ฉ์ ์ ์ ์์ธ ๋งคํผ๋ก, ์์ธ๋ฅผ ํน์ HTTP ์๋ต์ ๋งคํํ๋ค.
ExceptionMapper<ExpeditionNotFoundException> ๊ฐ ExpeditionNotFoundException ์ throw ๋๋ฉด,
์ด ๋งคํผ๋ HTTP 404 Not Found ์ํ์ ์์ธ ๋ฉ์์ง๋ฅผ ๋ฐํํ๋ค.
1. ์ผ๊ด๋ ์ฉ์ด ์ฌ์ฉ2. ์ ์ง๋ณด์์ ๋ฌธ์ํ3. ๋ณด์์ ์ต์ฐ์ ์ผ๋ก!4. ์ ์ ํ ์์ธ์ฒ๋ฆฌ
์ด 4๊ฐ์ง๋ฅผ ์งํค๋ฉด ๊ฒฌ๊ณ ํ REST API๋ฅผ ๊ฐ๋ฐํ๋๋ฐ ํฐ ๋์์ด ๋ ๊ฒ์ด๋ค.
โ
๋๋ฉ์ธ ์ฃผ๋ ์ค๊ณ(DDD)?
- ๊ธฐ๋ณธ ๋น์ฆ๋์ค ๋๋ฉ์ธ์ ๊ธฐ๋ฐ์ผ๋ก sw ๋ชจ๋ธ๋ง์ ์ด์ ์ ๋ง์ถ sw ์ค๊ณ ์ ๊ทผ ๋ฐฉ์
- ๋๋ฉ์ธ ๋ชจ๋ธ: ์ฝ๋ ์ค์ ๋๋ฉ์ธ์ ๋ฐ์
- ์ ๋น์ฟผํฐ์ค ์ธ์ด: ๊ฐ๋ฐ์์ ๋๋ฉ์ธ ์ ๋ฌธ๊ฐ๊ฐ ์ฌ์ฉํ๋ ๊ณตํต ์ธ์ด
- ์ ํ๋ ์ปจํ ์คํธ: ๋๋ฉ์ธ ๋ด์์ ์๋ก ๋ค๋ฅธ ๋ชจ๋ธ์ ๊ตฌ๋ถํ๋ ๋ช ํํ ๊ฒฝ๊ณ ์ญํ
- DDD๋ ์ํํธ์จ์ด ์ํคํ ์ฒ๋ฅผ ๋น์ฆ๋์ค ๋ชฉํ์ ๋ง์ถฐ ์กฐ์ ํ์ฌ ์ ์ง ๊ด๋ฆฌ ๊ฐ๋ฅ์ฑ๊ณผ ํ์ฅ์ฑ์ ๋์ด๋ ๋ฐ ๋์์ด ๋๋ค.
๐ค ์ด์ ๋ํ ๋์ ์๊ฐ
์ ๊ท์น์ค '๋ช ๊ฐ์ง๋ฅผ ์ ๋๋ก ์ค์ํ์๋๊ฐ?' ์๊ฐํด ๋ณด๊ฒ ๋์๋ค. ๋ํ ์ค๋ฅ ์ฒ๋ฆฌ์ ์ ์ ํ ์๋ต ์ฝ๋ ๋งคํ์ด ํ์์ ์ด๋ผ๋ ์ ์๋ ๋์ํ๋ค.
๊ทธ๋์ ๋ฌธ์ํ๋ ๋ฒ๊ฑฐ๋กญ๋ค๊ณ ์๊ฐํด์ 'ํ์'๋ผ๊ธฐ๋ณด๋ค๋ ์๊ฐ์ด ๋ ๋ ์ฒ๋ฆฌํ๋ฉด ์ข์ '์ ํ'์ด์๋ค๊ณ ์๊ฐํ๋๋ฐ, ์ค๋ ๊ธ์ ๋ณด๊ณ ์๊ฐ์ด ๋ฌ๋ผ์ก๋ค.
๋ฌด์๋ณด๋ค, "์ฌ์ฉ์๋ฅผ ์ ๋ขฐํ์ง ๋ง ๊ฒ" ์ด ๋๊ฒ ์ ์ ํ๊ณ ์ถฉ๊ฒฉ์ ์ด๋ค.
์ฌ์ฉ์๋ฅผ ์ํด ์กด์ฌํ์ง๋ง ๋ฌด์กฐ๊ฑด์ ์ผ๋ก ์ฌ์ฉ์๋ฅผ ์ ๋ขฐํ ์ ์๋ ์ด์ ๋ ์ ์์ ์ธ ๋ชฉ์ ์ ๊ฐ์ง ์ฌ์ฉ์๊ฐ ๋ง๊ธฐ ๋๋ฌธ์ด๋ผ๊ณ ์๊ฐํ๋ค.(์ ํํ ๋งํ๋ฉด ์ฌ์ฉ์๋ณด๋จ ๊ณต๊ฒฉ์์ ๊ฐ๊น๊ฒ ์ง..?)
์ด๋ฌํ ๊ด์ ์ ๋ณํ ํตํด ํฅํ ํ๋ก์ ํธ์์ ์ด๋ฌํ ์์น๋ค์ ์ ๊ฒฝ์จ์ ๊ตฌํํด์ผ๊ฒ ๋ค๊ณ ๋ค์งํ๊ฒ ๋์๋ค!