Skip to content

Commit

Permalink
crude working version for displaying multi docs
Browse files Browse the repository at this point in the history
planning on working on changing debug view to Expansion Panels
  • Loading branch information
jrhee17 committed Aug 7, 2019
1 parent 4a9e729 commit 2a7e1b5
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 90 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -152,20 +152,19 @@ private static void addServiceDescription(Map<Class<?>, String> serviceDescripti
private static void addMethodInfo(Map<Class<?>, Set<MethodInfo>> methodInfos,
String hostnamePattern, AnnotatedHttpService service) {
final List<Route> routes = service.routes();
routes.forEach(route -> {
final EndpointInfo endpoint = endpointInfo(route, hostnamePattern);
final Method method = service.method();
final String name = method.getName();
final TypeSignature returnTypeSignature = toTypeSignature(method.getGenericReturnType());
final List<FieldInfo> fieldInfos = fieldInfos(service.annotatedValueResolvers());
final Class<?> clazz = service.object().getClass();
route.methods().forEach(
httpMethod -> {
final MethodInfo methodInfo = new MethodInfo(
name, returnTypeSignature, fieldInfos, ImmutableList.of(), // Ignore exceptions.
ImmutableList.of(endpoint), httpMethod, findDescription(method));
methodInfos.computeIfAbsent(clazz, unused -> new HashSet<>()).add(methodInfo);
});
final List<EndpointInfo> endpointInfos =
routes.stream().map(route -> endpointInfo(route, hostnamePattern))
.collect(Collectors.toList());
final Method method = service.method();
final String name = method.getName();
final TypeSignature returnTypeSignature = toTypeSignature(method.getGenericReturnType());
final List<FieldInfo> fieldInfos = fieldInfos(service.annotatedValueResolvers());
final Class<?> clazz = service.object().getClass();
routes.stream().flatMap(route -> route.methods().stream()).forEach(httpMethod -> {
final MethodInfo methodInfo = new MethodInfo(
name, returnTypeSignature, fieldInfos, ImmutableList.of(), // Ignore exceptions.
endpointInfos, httpMethod, findDescription(method));
methodInfos.computeIfAbsent(clazz, unused -> new HashSet<>()).add(methodInfo);
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,13 @@ public HttpResponse exclude1() {
public HttpResponse exclude2() {
return HttpResponse.of(200);
}

@Get
@Path("/multi")
@Path("prefix:/multi2")
public HttpResponse multi() {
return HttpResponse.of(200);
}
}

private enum MyEnum {
Expand Down
78 changes: 76 additions & 2 deletions docs-client/src/containers/MethodPage/Endpoints.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,31 @@ import TableHead from '@material-ui/core/TableHead';
import TableRow from '@material-ui/core/TableRow';
import Typography from '@material-ui/core/Typography';
import * as React from 'react';
import { Endpoint, Method } from '../../lib/specification';
import {Endpoint, Method, Service, Specification} from '../../lib/specification';

import Section from '../../components/Section';
import DebugPage from "./DebugPage";
import {RouteComponentProps} from "react-router";
import {TRANSPORTS} from "../../lib/transports";
import {Option} from "react-dropdown";

interface Props {
interface OwnProps {
method: Method;
specification: Specification;
}

type Props = OwnProps &
RouteComponentProps<{
serviceName: string;
methodName: string;
httpMethod: string;
}>;

const Endpoints: React.SFC<Props> = (props) => {
const service = props.specification.getServiceByName(
props.match.params.serviceName,
);

return (
<Section>
<Typography variant="title">Endpoints</Typography>
Expand Down Expand Up @@ -69,6 +85,20 @@ const Endpoints: React.SFC<Props> = (props) => {
</ListItem>
))}
</List>
<DebugPage
{...props}
method={props.method}
isAnnotatedHttpService={TRANSPORTS.isAnnotatedService(props.method)}
exampleHeaders={
service ? getExampleHeaders(
props.specification,
service,
props.method,
) : []
}
exactPathMapping={TRANSPORTS.isAnnotatedService(props.method) ? isExactPathMapping(props.method) : false}
useRequestBody={useRequestBody(props.match.params.httpMethod)}
/>
</TableCell>
</TableRow>
))}
Expand All @@ -85,4 +115,48 @@ function endpointPathString(endpoint: Endpoint): string {
return endpoint.pathMapping;
}

function isExactPathMapping(method: Method): boolean {
const endpoints = method.endpoints;
const endpoint = endpoints[0];
return endpoint.pathMapping.startsWith('exact:');
}

function useRequestBody(httpMethod: string) {
return httpMethod === 'POST' || httpMethod === 'PUT';
}

function getExampleHeaders(
specification: Specification,
service: Service,
method: Method,
): Option[] {
const exampleHeaders: Option[] = [];
addExampleHeadersIfExists(exampleHeaders, method.exampleHttpHeaders);
addExampleHeadersIfExists(exampleHeaders, service.exampleHttpHeaders);
addExampleHeadersIfExists(
exampleHeaders,
specification.getExampleHttpHeaders(),
);
return exampleHeaders;
}

function addExampleHeadersIfExists(
dst: Option[],
src: { [name: string]: string }[],
) {
if (src.length > 0) {
for (const headers of src) {
dst.push({
value: JSON.stringify(headers, null, 2),
label: removeBrackets(JSON.stringify(headers).trim()),
});
}
}
}

function removeBrackets(headers: string): string {
const length = headers.length;
return headers.substring(1, length - 1).trim();
}

export default Endpoints;
79 changes: 7 additions & 72 deletions docs-client/src/containers/MethodPage/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,21 +23,14 @@ import TableCell from '@material-ui/core/TableCell';
import TableRow from '@material-ui/core/TableRow';
import Typography from '@material-ui/core/Typography';
import React from 'react';
import { Option } from 'react-dropdown';
import { RouteComponentProps } from 'react-router-dom';

import {
Method,
Service,
simpleName,
Specification,
} from '../../lib/specification';
import { TRANSPORTS } from '../../lib/transports';
import { ANNOTATED_HTTP_MIME_TYPE } from '../../lib/transports/annotated-http';
import {RouteComponentProps} from 'react-router-dom';

import {simpleName, Specification,} from '../../lib/specification';
import {TRANSPORTS} from '../../lib/transports';
import {ANNOTATED_HTTP_MIME_TYPE} from '../../lib/transports/annotated-http';

import Section from '../../components/Section';
import VariableList from '../../components/VariableList';
import DebugPage from './DebugPage';
import Endpoints from './Endpoints';
import Exceptions from './Exceptions';

Expand Down Expand Up @@ -107,73 +100,15 @@ const MethodPage: React.SFC<Props> = (props) => {
{!isAnnotatedHttpService && (
<Exceptions method={method} specification={props.specification} />
)}
<Endpoints method={method} />
{debugTransport && (
<DebugPage
{...props}
method={method}
isAnnotatedHttpService={isAnnotatedHttpService}
exampleHeaders={getExampleHeaders(
props.specification,
service,
method,
)}
exactPathMapping={
isAnnotatedHttpService ? isExactPathMapping(method) : false
}
useRequestBody={useRequestBody(props.match.params.httpMethod)}
/>
)}
<Endpoints {...props} method={method} specification={props.specification} />
</>
);
};

function getExampleHeaders(
specification: Specification,
service: Service,
method: Method,
): Option[] {
const exampleHeaders: Option[] = [];
addExampleHeadersIfExists(exampleHeaders, method.exampleHttpHeaders);
addExampleHeadersIfExists(exampleHeaders, service.exampleHttpHeaders);
addExampleHeadersIfExists(
exampleHeaders,
specification.getExampleHttpHeaders(),
);
return exampleHeaders;
}

function addExampleHeadersIfExists(
dst: Option[],
src: { [name: string]: string }[],
) {
if (src.length > 0) {
for (const headers of src) {
dst.push({
value: JSON.stringify(headers, null, 2),
label: removeBrackets(JSON.stringify(headers).trim()),
});
}
}
}

function removeBrackets(headers: string): string {
const length = headers.length;
return headers.substring(1, length - 1).trim();
}

function isExactPathMapping(method: Method): boolean {
const endpoints = method.endpoints;
if (endpoints.length !== 1) {
throw new Error(`
Endpoints size should be 1 to determine prefix or regex. size: ${endpoints.length}`);
}
const endpoint = endpoints[0];
return endpoint.pathMapping.startsWith('exact:');
}

function useRequestBody(httpMethod: string) {
return httpMethod === 'POST' || httpMethod === 'PUT';
}


export default MethodPage;
9 changes: 7 additions & 2 deletions docs-client/src/lib/transports/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@
* under the License.
*/

import { Method } from '../specification';
import {Method} from '../specification';

import AnnotatedHttpTransport from './annotated-http';
import AnnotatedHttpTransport, {ANNOTATED_HTTP_MIME_TYPE} from './annotated-http';
import GrpcUnframedTransport from './grpc-unframed';
import ThriftTransport from './thrift';
import Transport from './transport';
Expand Down Expand Up @@ -46,6 +46,11 @@ export class Transports {
}
return undefined;
}

public isAnnotatedService(method: Method): boolean {
const debugTransport = this.getDebugTransport(method);
return debugTransport !== undefined && debugTransport.supportsMimeType(ANNOTATED_HTTP_MIME_TYPE);
}
}

export const TRANSPORTS = new Transports();

0 comments on commit 2a7e1b5

Please sign in to comment.