Gamism.SDK.Core`와 `Gamism.SDK.Extensions.AspNetCore 패키지 사용 가이드입니다.
<PackageReference Include="Gamism.SDK.Core" Version="x.x.x" />
<PackageReference Include="Gamism.SDK.Extensions.AspNetCore" Version="x.x.x" />Program.cs`에 두 줄만 추가하면 모든 기능이 활성화됩니다. 각 기능은 기본적으로 활성화(`Enabled = true)되어 있습니다.
builder.Services.AddGamismSdk(options =>
{
options.ConfigureSwagger(swagger =>
{
swagger.Title = "My API";
swagger.PathsToMatch = ["/api/**"];
});
options.ConfigureLogging(logging =>
{
logging.NotLoggingUrls = ["/swagger/**", "/health"];
});
});
app.UseGamismSdk();서버와 클라이언트가 공유하는 공통 API 응답 포맷입니다.
{
"status": "OK",
"code": 200,
"message": "성공",
"data": <페이로드>
}데이터 없는 응답에 사용하는 빈 응답 타입입니다.
CommonApiResponse.Success(message), CommonApiResponse.Created(message) 등 data 없는 팩토리 메서드는 `CommonApiResponse<EmptyResponse>`의 서브클래스인 `CommonApiResponse`를 반환합니다. 컨트롤러 반환 타입에 `CommonApiResponse`를 그대로 사용할 수 있습니다.
// CommonApiResponse는 CommonApiResponse<EmptyResponse>를 상속
public CommonApiResponse CreateItem() =>
CommonApiResponse.Created("생성 완료");| 메서드 | HTTP Status | 반환 타입 | 설명 |
|---|---|---|---|
|
200 OK |
|
data 없음 |
|
200 OK |
|
data 포함 |
|
201 Created |
|
data 없음 |
|
201 Created |
|
data 포함 |
|
지정한 status |
|
data 없음 |
HTTP 요청과 응답을 자동으로 로깅합니다.
| 옵션 | 기본값 | 설명 |
|---|---|---|
|
|
로깅 필터 활성화 여부 |
|
|
로깅에서 제외할 URL 패턴 목록. ``는 경로 구분자를 제외한 모든 문자, `*`는 경로 구분자 포함 모든 문자와 매칭 |
options.ConfigureLogging(logging =>
{
logging.NotLoggingUrls = ["/health", "/swagger/**"];
// "/swagger/index.html", "/swagger/v1/swagger.json" 등 모두 제외됨
});컨트롤러의 모든 반환값을 CommonApiResponse<T> 형식으로 자동 래핑하는 필터(IAsyncResultFilter)입니다.
| 반환값 | HTTP Status | 동작 |
|---|---|---|
일반 객체 / |
200 OK |
|
|
204 No Content |
빈 응답 |
|
응답 내 |
그대로 통과 (이중 래핑 없음) |
[ApiController]
public class UserController : ControllerBase
{
[HttpGet("/users")]
public List<User> GetUsers()
{
// 자동으로 CommonApiResponse<List<User>>로 래핑됨
return _userService.GetAll();
}
[HttpPost("/users")]
public CommonApiResponse CreateUser(CreateUserRequest request)
{
// data 없음 → CommonApiResponse (CommonApiResponse<EmptyResponse> 서브클래스)
_userService.Create(request);
return CommonApiResponse.Created("생성 완료");
}
[HttpPost("/users/with-data")]
public CommonApiResponse<User> CreateUserWithData(CreateUserRequest request)
{
// data 포함 → CommonApiResponse<T>
return CommonApiResponse.Created("생성 완료", _userService.Create(request));
}
[HttpDelete("/users/{id}")]
public void DeleteUser(int id)
{
// void 반환 → 204 No Content
_userService.Delete(id);
}
}IActionResult`의 오류 반환 메서드(`NotFound(), BadRequest() 등)는 `ObjectResult`가 아니므로 래퍼를 거치지 않아 응답 형식이 깨집니다. 오류 응답은 반드시 `ExpectedException`을 사용하세요.
// ❌ body 없는 404 반환 — CommonApiResponse 형식이 아님
return NotFound();
// ✅ GlobalExceptionHandler가 CommonApiResponse 형식으로 변환
throw new NotFoundException("유저를 찾을 수 없습니다");| 옵션 | 기본값 | 설명 |
|---|---|---|
|
|
응답 래퍼 활성화 여부 |
|
|
래핑에서 제외할 URL 패턴 목록. |
options.ConfigureResponse(response =>
{
response.NotWrappingUrls = ["/swagger/**", "/health"];
});ExpectedException`을 던지면 `GlobalExceptionHandler`가 자동으로 처리하여 `CommonApiResponse 형식으로 응답합니다. 그 외 예외는 500으로 응답하고 스택 트레이스를 `ILogger`에 기록합니다.
// 메시지 직접 지정
throw new ExpectedException(HttpStatusCode.NotFound, "유저를 찾을 수 없습니다");
// status 기본 메시지 사용
throw new ExpectedException(HttpStatusCode.Forbidden);{
"status": "NOT_FOUND",
"code": 404,
"message": "유저를 찾을 수 없습니다"
}자주 쓰는 상태코드는 전용 클래스를 제공합니다.
| 클래스 | HTTP Status |
|---|---|
|
400 |
|
401 |
|
403 |
|
404 |
|
409 |
throw new NotFoundException("유저를 찾을 수 없습니다");
throw new ForbiddenException("접근 권한이 없습니다");`ExpectedException`은 스택 트레이스를 수집하지 않아 일반 예외보다 생성 비용이 낮습니다. 비즈니스 로직 오류 처리에 적합합니다.
| 옵션 | 기본값 | 설명 |
|---|---|---|
|
|
예외 핸들러 활성화 여부 |
Swashbuckle(9.x) 기반의 Swagger UI를 자동으로 구성합니다. 응답 스키마는 CommonApiResponse 래핑 구조를 반영합니다.
| 옵션 | 기본값 | 설명 |
|---|---|---|
|
|
Swagger 활성화 여부 |
|
|
API 문서 제목 |
|
|
API 문서 설명 |
|
|
API 버전 |
|
|
API 그룹명 |
|
|
문서화할 경로 패턴 목록. |
options.ConfigureSwagger(swagger =>
{
swagger.Title = "My API";
swagger.Version = "v1";
swagger.PathsToMatch = ["/api/**"];
});builder.Services.AddGamismSdk(options =>
{
options.ConfigureException(exception =>
{
exception.Enabled = true;
});
options.ConfigureResponse(response =>
{
response.Enabled = true;
response.NotWrappingUrls = ["/swagger/**", "/health"];
});
options.ConfigureLogging(logging =>
{
logging.Enabled = true;
logging.NotLoggingUrls = ["/swagger/**", "/health"];
});
options.ConfigureSwagger(swagger =>
{
swagger.Enabled = true;
swagger.Title = "My API";
swagger.Description = "My API Description";
swagger.Version = "v1";
swagger.Group = "default";
swagger.PathsToMatch = ["/api/**"];
});
});
app.UseGamismSdk();