Add interceptor hook for graphql calls
This commit is contained in:
parent
a1e1cf4e56
commit
b4fece0ae9
|
@ -631,7 +631,10 @@ public class FhirContext {
|
|||
* Performance Note: <b>This method is cheap</b> to call, and may be called once for every message being processed
|
||||
* without incurring any performance penalty
|
||||
* </p>
|
||||
*
|
||||
* @deprecated THIS FEATURE IS NOT YET COMPLETE
|
||||
*/
|
||||
@Deprecated
|
||||
public IParser newRDFParser() {
|
||||
return new RDFParser(this, myParserErrorHandler, Lang.TURTLE);
|
||||
}
|
||||
|
|
|
@ -374,6 +374,57 @@ public enum Pointcut {
|
|||
),
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* <b>Server Hook:</b>
|
||||
* This method is called after the server implementation method has been called, but before any attempt
|
||||
* to stream the response back to the client, specifically for GraphQL requests (as these do not fit
|
||||
* cleanly into the model provided by {@link #SERVER_OUTGOING_RESPONSE}).
|
||||
* <p>
|
||||
* Hooks may accept the following parameters:
|
||||
* <ul>
|
||||
* <li>
|
||||
* ca.uhn.fhir.rest.api.server.RequestDetails - A bean containing details about the request that is about to be processed, including details such as the
|
||||
* resource type and logical ID (if any) and other FHIR-specific aspects of the request which have been
|
||||
* pulled out of the servlet request.
|
||||
* </li>
|
||||
* <li>
|
||||
* ca.uhn.fhir.rest.server.servlet.ServletRequestDetails - A bean containing details about the request that is about to be processed, including details such as the
|
||||
* resource type and logical ID (if any) and other FHIR-specific aspects of the request which have been
|
||||
* pulled out of the servlet request. This parameter is identical to the RequestDetails parameter above but will
|
||||
* only be populated when operating in a RestfulServer implementation. It is provided as a convenience.
|
||||
* </li>
|
||||
* <li>
|
||||
* java.lang.String - The GraphQL query
|
||||
* </li>
|
||||
* <li>
|
||||
* java.lang.String - The GraphQL response
|
||||
* </li>
|
||||
* <li>
|
||||
* ca.uhn.fhir.rest.api.server.ResponseDetails - This object contains details about the response, including the contents. Hook methods may modify this object to change or replace the response.
|
||||
* </li>
|
||||
* </ul>
|
||||
* </p>
|
||||
* <p>
|
||||
* Hook methods may return <code>true</code> or <code>void</code> if processing should continue normally.
|
||||
* This is generally the right thing to do. If your interceptor is providing a response rather than
|
||||
* letting HAPI handle the response normally, you must return <code>false</code>. In this case,
|
||||
* no further processing will occur and no further interceptors will be called.
|
||||
* </p>
|
||||
* <p>
|
||||
* Hook methods may also throw {@link AuthenticationException} to indicate that the interceptor
|
||||
* has detected an unauthorized access attempt. If thrown, processing will stop and an HTTP 401
|
||||
* will be returned to the client.
|
||||
*/
|
||||
SERVER_OUTGOING_GRAPHQL_RESPONSE(boolean.class,
|
||||
"ca.uhn.fhir.rest.api.server.RequestDetails",
|
||||
"ca.uhn.fhir.rest.server.servlet.ServletRequestDetails",
|
||||
"java.lang.String",
|
||||
"java.lang.String",
|
||||
"ca.uhn.fhir.rest.api.server.ResponseDetails"
|
||||
),
|
||||
|
||||
|
||||
/**
|
||||
* <b>Server Hook:</b>
|
||||
* This method is called when an OperationOutcome is being returned in response to a failure.
|
||||
|
|
|
@ -219,6 +219,7 @@ public class Constants {
|
|||
public static final int MAX_RESOURCE_NAME_LENGTH = 100;
|
||||
public static final String CACHE_CONTROL_PRIVATE = "private";
|
||||
public static final int STATUS_HTTP_412_PAYLOAD_TOO_LARGE = 413;
|
||||
public static final String OPERATION_NAME_GRAPHQL = "$graphql";
|
||||
|
||||
static {
|
||||
CHARSET_UTF8 = Charset.forName(CHARSET_NAME_UTF8);
|
||||
|
|
|
@ -49,7 +49,9 @@ public enum EncodingEnum {
|
|||
public IParser newParser(FhirContext theContext) {
|
||||
return theContext.newRDFParser();
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
;
|
||||
|
||||
/**
|
||||
* "json"
|
||||
|
|
|
@ -109,7 +109,7 @@ public class GraphQLProvider {
|
|||
}
|
||||
|
||||
@GraphQL
|
||||
public String processGraphQlRequet(ServletRequestDetails theRequestDetails, @IdParam IIdType theId, @GraphQLQuery String theQuery) {
|
||||
public String processGraphQlRequest(ServletRequestDetails theRequestDetails, @IdParam IIdType theId, @GraphQLQuery String theQuery) {
|
||||
|
||||
IGraphQLEngine engine = engineFactory.get();
|
||||
engine.setAppInfo(theRequestDetails);
|
||||
|
|
|
@ -21,16 +21,19 @@ package ca.uhn.fhir.rest.server.method;
|
|||
*/
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.interceptor.api.HookParams;
|
||||
import ca.uhn.fhir.interceptor.api.Pointcut;
|
||||
import ca.uhn.fhir.rest.api.Constants;
|
||||
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
|
||||
import ca.uhn.fhir.rest.api.server.IRestfulServer;
|
||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||
import ca.uhn.fhir.rest.param.ParameterUtil;
|
||||
import ca.uhn.fhir.rest.server.RestfulServer;
|
||||
import ca.uhn.fhir.rest.server.RestfulServerUtils;
|
||||
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
|
||||
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
import java.lang.reflect.Method;
|
||||
|
@ -63,7 +66,7 @@ public class GraphQLMethodBinding extends BaseMethodBinding<String> {
|
|||
|
||||
@Override
|
||||
public boolean incomingServerRequestMatchesMethod(RequestDetails theRequest) {
|
||||
if ("$graphql".equals(theRequest.getOperation())) {
|
||||
if (Constants.OPERATION_NAME_GRAPHQL.equals(theRequest.getOperation())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -85,11 +88,22 @@ public class GraphQLMethodBinding extends BaseMethodBinding<String> {
|
|||
String charset = Constants.CHARSET_NAME_UTF8;
|
||||
boolean respondGzip = theRequest.isRespondGzip();
|
||||
|
||||
Writer writer = theRequest.getResponse().getResponseWriter(statusCode, statusMessage, contentType, charset, respondGzip);
|
||||
|
||||
String responseString = (String) response;
|
||||
writer.write(responseString);
|
||||
writer.close();
|
||||
|
||||
// Interceptor call: SERVER_OUTGOING_GRAPHQL_RESPONSE
|
||||
HookParams params = new HookParams()
|
||||
.add(RequestDetails.class, theRequest)
|
||||
.addIfMatchesType(ServletRequestDetails.class, theRequest)
|
||||
.add(String.class, theRequest.getParameters().get(Constants.PARAM_GRAPHQL_QUERY)[0])
|
||||
.add(String.class, responseString);
|
||||
if (theRequest.getInterceptorBroadcaster().callHooks(Pointcut.SERVER_OUTGOING_GRAPHQL_RESPONSE, params)) {
|
||||
|
||||
// Write the response
|
||||
Writer writer = theRequest.getResponse().getResponseWriter(statusCode, statusMessage, contentType, charset, respondGzip);
|
||||
writer.write(responseString);
|
||||
writer.close();
|
||||
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -6,6 +6,15 @@
|
|||
<title>HAPI FHIR Changelog</title>
|
||||
</properties>
|
||||
<body>
|
||||
<!--
|
||||
<release version="4.1.0" date="TBD" description="Igloo">
|
||||
<action type="add" issue="1321">
|
||||
Support has been added for RDF encoding and parsing in the
|
||||
<![CDATA[<a href="https://www.hl7.org/fhir/rdf.html#instance">Turtle</a>]]>
|
||||
format. Thanks to Raul Estrada for the pull request!
|
||||
</action>
|
||||
</release>
|
||||
-->
|
||||
<release version="4.0.0" date="TBD" description="Igloo">
|
||||
<action type="add">
|
||||
The version of a few dependencies have been bumped to the
|
||||
|
@ -135,11 +144,6 @@
|
|||
</li>The rule list is now cached on a per-request basis, which should improve performance</ul>
|
||||
]]>
|
||||
</action>
|
||||
<action type="add" issue="1321">
|
||||
Support has been added for RDF encoding and parsing in the
|
||||
<![CDATA[<a href="https://www.hl7.org/fhir/rdf.html#instance">Turtle</a>]]>
|
||||
format. Thanks to Raul Estrada for the pull request!
|
||||
</action>
|
||||
<action type="add">
|
||||
The $expunge global everything operation has been refactored to do deletes
|
||||
in small batches. This change will likely reduce performance, but does allow
|
||||
|
|
Loading…
Reference in New Issue