-
Notifications
You must be signed in to change notification settings - Fork 926
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix that overloaded methods are not displayed in DocService #4545
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does front-end need to know about overloadId
?
println(json5Mapper.writerWithDefaultPrettyPrinter().writeValueAsString(response.get("services").get(0).get("methods"))) | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like a leftover
m.httpMethod === props.match.params.httpMethod, | ||
); | ||
const id = `${params.serviceName}/${params.methodName}/${params.httpMethod}`; | ||
const method = service.methods.find((m) => m.id === id); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 Great to see this change, did we have issues with overlapping method names from different services in the previous version?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
overlapping method names from different services in the previous version?
No, we didn't have such an issue. We have issues only with the same service. For example:
class MyAnnotatedService {
@Get("/foo)
public HttpResponse foo() {...}
@Get("/foo1)
public HttpResponse foo(MyType type) {...} <--- This isn't rendered.
}
class YourAnnotatedService {
@Get("/foo2)
public HttpResponse foo() {...} // Rendered correctly
}
@@ -354,7 +373,7 @@ private static void addMarkdownDescriptionMethodInfo(Map<Class<?>, Set<MethodInf | |||
.descriptionInfo(DescriptionInfo.of("DESCRIPTION `PARAM`", Markup.MARKDOWN)) | |||
.build()); | |||
final MethodInfo methodInfo = new MethodInfo( | |||
"description", STRING, fieldInfos, ImmutableList.of(), | |||
MyService.class.getName(), "description", 0, STRING, fieldInfos, ImmutableList.of(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just double-checking, does this include the package name?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes and let me show later how we find the corresponding struct in StructInfo
or enum
in EnumInfo
later. 😉
/** | ||
* Container type. | ||
*/ | ||
CONTAINER(true, false), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is an example for a container type? Maybe generics? Like Id<T>
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One example would be:
Line 518 in 6bd02dc
public BiFunction<JsonNode, ?, String> consumes() { |
Of course, we cannot represent this type with JSON schema so I'm thinking we just need to omit such fields
and add "additionalProperties": "true"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it is something simple like public class Box<T> { public T shape; ... }
I guess FieldInfo
will already contain what we have put inside T
right? If not, the user might need to find out that from additional properties (which seems mostly redundant, I agree with you.)
@@ -254,41 +255,7 @@ | |||
"location": "UNSPECIFIED", | |||
"requirement": "OPTIONAL", | |||
"typeSignature": "armeria.protobuf.testing.SimpleOneof", | |||
"childFieldInfos": [ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just double checking, are we removing childFieldInfos
from the return type signatures for all types? What is this about?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a bug. There's a recursion so I removed it. You can find armeria.protobuf.testing.SimpleOneof"
in two levels above.
Codecov ReportBase: 74.08% // Head: 74.05% // Decreases project coverage by
Additional details and impacted files@@ Coverage Diff @@
## master #4545 +/- ##
============================================
- Coverage 74.08% 74.05% -0.03%
+ Complexity 18190 18186 -4
============================================
Files 1537 1542 +5
Lines 67432 67530 +98
Branches 8533 8549 +16
============================================
+ Hits 49959 50012 +53
- Misses 13401 13438 +37
- Partials 4072 4080 +8
Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. ☔ View full report at Codecov. |
Nope. |
m.name === props.match.params.methodName && | ||
m.httpMethod === props.match.params.httpMethod, | ||
); | ||
const id = `${params.serviceName}/${params.methodName}/${params.httpMethod}`; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we include overloadId
here as well then?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, we shouldn't. 😉
params.methodName
is the path parameter that is inserted from the Router.
path="/methods/:serviceName/:methodName/:httpMethod" |
It could be
overload-1
which already has the overloadId if a user types or navigates through the link.
core/src/main/java/com/linecorp/armeria/server/docs/TypeSignatureType.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/linecorp/armeria/server/docs/ContainerTypeSignature.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/linecorp/armeria/server/docs/DefaultTypeSignature.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/linecorp/armeria/server/docs/NamedTypeSignature.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/linecorp/armeria/server/docs/TypeSignatureType.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/linecorp/armeria/server/docs/MethodInfo.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/linecorp/armeria/server/docs/NamedTypeSignature.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/linecorp/armeria/server/docs/DefaultTypeSignature.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/linecorp/armeria/server/docs/TypeSignature.java
Outdated
Show resolved
Hide resolved
.../main/java/com/linecorp/armeria/internal/server/annotation/DefaultNamedTypeInfoProvider.java
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ikhoon Addressed your comments so PTAL.
Thanks a lot for the detailed review. 😉
core/src/main/java/com/linecorp/armeria/server/docs/DefaultTypeSignature.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/linecorp/armeria/server/docs/MethodInfo.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/linecorp/armeria/server/docs/NamedTypeSignature.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/linecorp/armeria/server/docs/NamedTypeSignature.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/linecorp/armeria/server/docs/TypeSignature.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/linecorp/armeria/server/docs/TypeSignatureType.java
Outdated
Show resolved
Hide resolved
grpc/src/main/java/com/linecorp/armeria/internal/server/grpc/GrpcDocServicePlugin.java
Outdated
Show resolved
Hide resolved
.../main/java/com/linecorp/armeria/internal/server/annotation/DefaultNamedTypeInfoProvider.java
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@@ -412,7 +419,7 @@ static TypeSignature toTypeSignature(Type type) { | |||
return TypeSignature.ofList(toTypeSignature(clazz.getComponentType())); | |||
} | |||
|
|||
return TypeSignature.ofNamed(clazz); | |||
return TypeSignature.ofStruct(clazz); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
|
||
@Override | ||
public String signature() { | ||
return name() + '<' + Joiner.on(", ").join(typeParameters) + '>'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Joiner.on(...)
creates a new object. Should we use a static variable?
https://github.com/google/guava/wiki/StringsExplained#joiner
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Copied the previous logic without much thinking. 😅 Thanks!
requireNonNull(namedTypeInfoProviders, "namedTypeInfoProviders"); | ||
for (NamedTypeInfoProvider typeInfoProvider : namedTypeInfoProviders) { | ||
namedTypeInfoProvider(typeInfoProvider); | ||
public DocServiceBuilder descriptiveTypeInfoProvider( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems like I missed adding @UnstableApi
. 😅 Could you add it to this method and below?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops, added. 😉
@@ -169,7 +209,7 @@ public MethodInfo withParameters(Iterable<FieldInfo> parameters) { | |||
|
|||
return new MethodInfo(name, returnTypeSignature, parameters, exceptionTypeSignatures, endpoints, | |||
exampleHeaders, exampleRequests, examplePaths, exampleQueries, httpMethod, | |||
descriptionInfo); | |||
descriptionInfo, id); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops... I found the Javadoc is incorrect. Could you fix it as well? 😅
Let me merge this so I can continue to add JSON schema type for @Dogacel's work. |
@minwoox Thanks a lot 🙇 I haven't been able to look at armeria for the last couple of weeks because this PR was waiting on open status. Are there any help needed? I expect the changes to be trivial, mostly enum logic will change. |
Yes, I need your help. 😄 |
Motivation:
Overloaded methods in annotated services are not displayed correctly in DocService.
Armeria DocService was built for Thrift services in which overloading methods are not possible, so we didn't consider overloaded methods at that time.
Also, it was for Thrift types, the
TypeSignature
wasn't structured well to represent other types used ingRPC
and annotated services.Modifications:
id
toMethodInfo
that uniquely identifies each method.serviceName/methodName/httpMethod
methodName
has increased-n
at the end when the method is overloaded.TypeSigniture
.TypeSignatureType
that represents eachTypeSignature
NamedTypeInfo.findNamedTypes()
now returnsSet<NamedTypeSignature>
.Result:
DocService
when the method is overloaded.TypeSignature
To-do:
JsonSchemaType
toTypeSignature
for creating the JSON schema easily.