CustomContext 생성하기

GraphQL의 요청을 핸들링하는 GraphQLServletContextBuilder를 implements하여 grpahQL요청에 대해 커스텀Context를 반환하도록 만들 수 있다.

예를들어 요청의 헤더에 접근하여 Context에 특정 헤더값을 저장하는 식으로의 custom이 가능하다. 이번 예시에서는 헤더에 api-key가 포함되어있고 이 key를 분리하여 context도 저장하고있는 context를 만들어보려고 한다.


1. CustomContext 정의

GraphQLServletContext를 implements하여 총6개의 메서드들을 정의해주면 된다.

@Getter
@RequiredArgsConstructor
public class CustomGraphQLContext implements GraphQLServletContext {

    private final String apiKey;
    private final GraphQLServletContext context;

    @Override
    public List<Part> getFileParts() {
        return context.getFileParts();
    }

    @Override
    public Map<String, List<Part>> getParts() {
        return context.getParts();
    }

    @Override
    public HttpServletRequest getHttpServletRequest() {
        return context.getHttpServletRequest();
    }

    @Override
    public HttpServletResponse getHttpServletResponse() {
        return context.getHttpServletResponse();
    }

    @Override
    public Optional<Subject> getSubject() {
        return context.getSubject();
    }

    @Override
    public DataLoaderRegistry getDataLoaderRegistry() {
        return context.getDataLoaderRegistry();
    }
}

기본적인 ServletContext의 정보를 갖고있을 context 변수와 예시로 헤더값에 포함된 api-key를 저장할 필드를 포함한 커스텀context를 정의 해주면 된다.


2. GraphQLServeltContextBuilder

실제로 GraphQLServletContext를 생성하는 Builder도 구현해주어야 우리가 생성한 CustomContext로 Context가 생성이 된다.

@Component
@RequiredArgsConstructor
public class CustomGraphQLContextBuilder implements GraphQLServletContextBuilder {

    @Override
    public GraphQLContext build(HttpServletRequest httpServletRequest,
                                HttpServletResponse httpServletResponse) {

        String apiKey = httpServletRequest.getHeader("api-key");

        DefaultGraphQLServeltContext context = DefaultGraphQLServletContext.createServletContext()
                .with(httpServletRequest)
                .with(httpServletResponse)
                .build();

        return new CustomGraphQLContext(apiKey, context);
    }

    @Override
    public GraphQLContext build(Session session, HandshakeRequest handshakeRequest) {
        throw new IllegalStateException("Unsupported");
    }

    @Override
    public GraphQLContext build() {
        throw new IllegalStateException("Unsupported");
    }
}

build() 메서드 3개를 Override해 정의 해주어야 하는데, session방식은 사용하지 않기 때문에 Exception처리 해주었고 build의 매개변수인 httpServletRequest의 getHeader를 통해 api-key의 값을 꺼내고 만들어둔 CustomGraphQLContext에 apiKey를 포함하여 return하면 실제 QueryResolver를 처리하는 Context는 우리가 만든 CustomContext가 처리하게 된다.

그래서 이전에 설명한 Environment의 getContext() 메서드를 통해서 특정 필드에 접근도 가능하다.

@Component
@Slf4j
public class WetayoQuery implements GraphQLQueryResolver {
    //... 각종 Service들과 Constructor

    public List<RouteStationGraphQLDto> getStations(Double x, Double y, Double distance, DataFetchingEnvironment e) {
        CustomGraphQLContext context = e.getContext();
        log.info(context.getApiKey());  //헤더의 api-key  값 출력

        if(!context.getApiKey().equals("123456789")) throw new UnAuthorizedAccessExeption("유효하지 않은 api key");

        //비즈니스 로직

        return routeStationDtos;
    }
}

위와 같이 Controller의 메서드에서 context의 필드에도 접근,조회가 가능하게 된다. 하지만 위의 방법은 단일 책임 원칙에 위배되고 AOP스럽지도 못하기 때문에 썩 그렇게 좋은 코드는 아니고 예시로만 봐주면 될 것 같다.

Related Posts

Home Server 만들기

Home Server 만들기

집 서버를 만들게 된 배경 집 컴퓨터를 교체하고 지인의 컴퓨터를 교체해주면서 부품들이 여럿 남게 되는 상황이 생겼는데, 그냥 버리기 아까워 컴퓨터를 한대 더 조립을 하게 되었다. 사양은 Intel(R) Celeron(R) CPU G3930 에 4G, 250Gb 이다. 컴퓨터를 조립 후 막상 사용할 곳이 없어 고민하던 중에 aws 프리티어도 끝났겠다 싶어 개발이나 테스트용으로 서버를 사용하면 좋을 것 같아 서버로 만들어보기로 했다....

Read More
Spring Security Cors Mapping Error

Spring Security Cors Mapping Error

  • Error
  • 2022년 2월 14일

CORS 란? Cross-Stie HTTP Requests의 약자로 한 도메인이 다른 도메인의 자원을 사용하는 것을 의미하는데, chrome cors 기본정책이 strict-origin-when-cross-origin으로 Same Origin에 대해서만 자원을 사용하도록 제한되어 있다. 여기서 Same-Origin이란 호스트명, 프로토콜, 포트가 같은 도메인을 말한다. Front 서버와 Back서버를 나눠 개발을 진행하다 보면 두 주소(포트)가 달라 cors에러가 발생한다. 그래서 서버단에서 특정 origin을 허용할 수 있게 cors설정을 추가로 해주어야 한다....

Read More
한국공학대학교 S/W 경진대회 예선 후기

한국공학대학교 S/W 경진대회 예선 후기

학교공부에 치여 살다보니 알고리즘 문제 풀이를 안한지 3달정도가 지났는 데 학교 엘레베이터에 위와 같은 코테 포스터가 붙여진 것을 보았는데 실력 테스트도 해보고 상금도 노릴겸 해서 겸사겸사 신청을 했다. 대회 시상관련은 본선 진출시 기념품과, 대상 1명 50만원, 우수상 7명 30만원, 장려상 15명 10만원이었다. 사실 예선 통과후 본선에 들면 40명중 절반 이상인 23명안에만 들어도 10만원의 상금을 준다는 것을 보고 10만원을 목표로 신청했다....

Read More