Replies: 2 comments 9 replies
-
And, if that's intentional and desirable, I'd suggest we add a public |
Beta Was this translation helpful? Give feedback.
0 replies
-
E.g. I currently need to do sth. like this: import type { AnyMessage, Message, MessageType, PartialMessage } from '@bufbuild/protobuf';
import md5 from 'md5';
import type { EnhancedContext } from './context';
import type { UnaryImpl } from './service';
export function cacheServiceMethod<TInput extends Message<TInput>, TOutput extends Message<TOutput>>(
implementation: UnaryImpl<TInput, TOutput, EnhancedContext>,
ttl: number | string = '1 minute',
): UnaryImpl<TInput, TOutput, EnhancedContext> {
return async (request, ctx) => {
const cachePrefix = `grpc.${ctx.context.service.typeName}.${ctx.context.method.name}`;
const cacheSuffix = md5(request.toBinary({ writeUnknownFields: false }));
const cacheKey = `${cachePrefix}:${cacheSuffix}`;
const cacheValue = await ctx.cache.getBuffer(cacheKey);
const messageType = ctx.context.method.O as MessageType<TOutput>;
if (cacheValue !== null) {
return messageType.fromBinary(cacheValue, { readUnknownFields: false });
}
const methodResult = normalize(await implementation(request, ctx), messageType);
const methodResultBinary = methodResult.toBinary({ writeUnknownFields: false });
await ctx.cache.setBuffer(cacheKey, Buffer.from(methodResultBinary), ttl);
return methodResult;
};
}
function normalize<TMessage extends Message<TMessage> = AnyMessage>(
output: PartialMessage<TMessage> | TMessage,
type: MessageType<TMessage>,
): TMessage {
return output instanceof type ? output : new type(output as PartialMessage<TMessage>);
} |
Beta Was this translation helpful? Give feedback.
9 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
I am currently wondering whether allowing
PartialMessage
to be returned from service methods is a good idea or not. By adding ambiguouity there, it makes it harder to implement generic decorators / wrappers for service methods that could otherwise easily deal with the returned messages.For instance, a generic logging or caching wrapper that wraps
MethodImpl
now needs to check the returned value from the underlying implementation and possibly cast it into a proper message.I think it would be a better developer experience overal if service method implementations were strictly required to return proper messages.
Or is there a reason why this is allowed currently?
Beta Was this translation helpful? Give feedback.
All reactions