Skip to content

Commit

Permalink
Display request headers (#1978)
Browse files Browse the repository at this point in the history
* feat: display request headers

* chore: add changeset
  • Loading branch information
timonrey authored Apr 23, 2024
1 parent 394a5da commit f38864b
Show file tree
Hide file tree
Showing 14 changed files with 243 additions and 12 deletions.
6 changes: 6 additions & 0 deletions .changeset/tame-falcons-hear.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@commercetools-docs/gatsby-transformer-raml': patch
'@commercetools-docs/gatsby-theme-api-docs': patch
---

Request headers are now being displayed in the endpoints.
2 changes: 1 addition & 1 deletion api-specs/api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@
"generate-ramldoc:watch": "npx rmf-codegen generate ./api.raml -w -o ../../websites/api-docs-smoke-test/src/api-specs/api -t RAML_DOC --inline-examples"
},
"dependencies": {
"@commercetools-docs/rmf-codegen": "13.30.0"
"@commercetools-docs/rmf-codegen": "13.34.0"
}
}
37 changes: 37 additions & 0 deletions api-specs/test/api.raml
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,43 @@ uses:
type: object
example: !include examples/action-success.json

/namespace-action-with-headers:
uriParameters:
namespace:
displayName: Namespace
type: string
description: The namespace where the action to invoked is located.
action:
displayName: Action
type: string
description: The name of the action to invoked.
get:
headers:
Accept:
displayName: Accept Header
type: string
description: Accept application/json Header.
required: true
pattern: application/json
default: application/json
Test-Header:
displayName: Header with special type.
type: objects.ObjectTestType
description: A header with a special type.
Path-Header:
displayName: Path Header
type: string
required: true
pattern: ^/.*$
description: Use the GET method to allow the frontend to fetch data from a backend system. For the response, we recommend to use standard HTTP codes and `application/json` encoded content. The response will be structured as defined by the body property of the action.
responses:
200:
description: The response will be structured as defined by the body property of the action.
body:
application/json:
type: object
example: !include examples/action-success.json

/json-serializable-primitive-type:
put:
description: Use the PUT method to write data to a backend system. Any JSON serializable payload is accepted. The following request example adds a product to a cart. For the response, we recommend to use standard HTTP codes and `application/json` encoded content. The response will be structured [as defined by the `body` property of the action](/). The following response example contains the updated cart information, which includes the added product.
Expand Down
2 changes: 1 addition & 1 deletion api-specs/test/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@
"generate-ramldoc:watch": "npx rmf-codegen generate ./api.raml -w -o ../../websites/api-docs-smoke-test/src/api-specs/test -t RAML_DOC --inline-examples"
},
"dependencies": {
"@commercetools-docs/rmf-codegen": "13.30.0"
"@commercetools-docs/rmf-codegen": "13.34.0"
}
}
2 changes: 1 addition & 1 deletion packages/gatsby-theme-api-docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
"unist-util-visit": "5.0.0"
},
"devDependencies": {
"@commercetools-docs/rmf-codegen": "13.30.0",
"@commercetools-docs/rmf-codegen": "13.34.0",
"gatsby": "5.12.12",
"react": "18.2.0",
"react-dom": "18.2.0"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
import React from 'react';
import PropTypes from 'prop-types';
import styled from '@emotion/styled';
import {
Markdown,
designSystem as uiKitDesignSystem,
} from '@commercetools-docs/ui-kit';
import SpacingsStack from '@commercetools-uikit/spacings-stack';
import SpacingsInline from '@commercetools-uikit/spacings-inline';
import useTypesToRender from '../../../hooks/use-type-to-render';
import Required from '../../required';
import Table from '../../table';
import Title from './title';
import { DescriptionText } from '../../description';
import Info from '../../info';
import { typography } from '../../../design-system';

// inline-blocks inside a block are wrapped first before wrapping inline.
// this implements a wrapping behavior where property name and type are separated
// into lines before the name is wrapped in itself if it consists of multiple words.
const HeaderName = styled.div`
display: inline-block;
margin-right: ${uiKitDesignSystem.dimensions.spacings.s};
white-space: nowrap;
line-height: ${typography.lineHeights.propertyType};
`;
const HeaderType = styled.div`
display: inline-block;
line-height: ${typography.lineHeights.propertyType};
color: ${uiKitDesignSystem.colors.light.textFaded};
`;

const Pattern = styled.code`
color: ${uiKitDesignSystem.colors.light.textHighlight};
letter-spacing: 0.03em;
`;

const Headers = (props) => {
return (
<SpacingsStack scale="xs">
{props.title && <Title>{props.title}:</Title>}
<Table>
<tbody>
{props.headers.map((header) => {
return (
<HeaderRow
key={header.name}
apiKey={props.apiKey}
header={header}
/>
);
})}
</tbody>
</Table>
</SpacingsStack>
);
};
Headers.propTypes = {
apiKey: PropTypes.string,
title: PropTypes.string,
headers: PropTypes.arrayOf(
PropTypes.shape({
displayName: PropTypes.string.isRequired,
header: PropTypes.string.isRequired,
type: PropTypes.string.isRequired,
description: PropTypes.string,
required: PropTypes.bool,
pattern: PropTypes.string,
enum: PropTypes.string,
}).isRequired
).isRequired,
};
Headers.displayName = 'Headers';

function HeaderRow(props) {
const typesToRender = useTypesToRender({
property: props.header,
apiKey: props.apiKey,
isParameter: false,
});
const typeToRender = typesToRender[0]; // safe as we expect a single item in the array

return (
<tr key={props.header.displayName}>
<td>
<HeaderName>
<SpacingsInline scale="xs">
<Markdown.InlineCode>{props.header.header}</Markdown.InlineCode>
{props.header.required && <Required />}
</SpacingsInline>
</HeaderName>
{'\u200B' /* zero-width space for the search crawler */}
<HeaderType>
{typeToRender.displayPrefix && typeToRender.displayPrefix}

{typeToRender.type}
</HeaderType>
{'\u200B' /* zero-width space for the search crawler */}
</td>
<td>
<SpacingsStack scale="xs">
{props.header.description && (
<DescriptionText markdownString={props.header.description} />
)}
{props.header.pattern && (
<div>
<Info>
Pattern: <Pattern>{props.header.pattern}</Pattern>
</Info>
</div>
)}
</SpacingsStack>
</td>
</tr>
);
}
HeaderRow.propTypes = {
apiKey: PropTypes.string,
header: PropTypes.shape({
displayName: PropTypes.string.isRequired,
header: PropTypes.string.isRequired,
type: PropTypes.string.isRequired,
description: PropTypes.string,
required: PropTypes.bool,
pattern: PropTypes.string,
enum: PropTypes.string,
}).isRequired,
};
HeaderRow.displayName = 'HeaderRow';

export default Headers;
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { generateEndpointURN } from '../../../utils/ctp-urn';
import { tokens, dimensions, colors, typography } from '../../../design-system';
import Url from './url';
import Scopes from './scopes';
import Headers from './headers';
import Responses from './responses';
import Parameters from './parameters';
import QueryParameters from './query-parameters';
Expand Down Expand Up @@ -154,6 +155,14 @@ const Method = ({
/>
)}

{method.headers && (
<Headers
apiKey={apiKey}
title={'Request headers'}
headers={method.headers}
/>
)}

{method.body && (
<RequestRepresentation
apiKey={apiKey}
Expand Down
10 changes: 10 additions & 0 deletions packages/gatsby-theme-api-docs/src/hooks/use-api-resources.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,16 @@ export const useApiResources = () => {
type
}
}
headers {
header
displayName
default
enum
description
type
required
pattern
}
responses {
code
description
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const defineRamlResource = ({ schema, createTypes }) => {
displayName: String
description: String
queryParameters: [RamlResourceQueryParameter!]
headers: [RamlResourceHeaders!]
responses: [RamlResourceResponse!]
codeExamples: [RamlResourceCodeExample!]
}
Expand Down Expand Up @@ -49,6 +50,7 @@ const defineRamlResource = ({ schema, createTypes }) => {
displayName: 'String',
description: 'String',
queryParameters: '[RamlResourceQueryParameter!]',
headers: '[RamlResourceHeaders!]',
body: 'RamlResourceMethodBody',
responses: '[RamlResourceResponse!]',
codeExamples: '[RamlResourceCodeExample!]',
Expand All @@ -63,6 +65,7 @@ const defineRamlResource = ({ schema, createTypes }) => {
displayName: 'String',
description: 'String',
queryParameters: '[RamlResourceQueryParameter!]',
headers: '[RamlResourceHeaders!]',
responses: '[RamlResourceResponse!]',
codeExamples: '[RamlResourceCodeExample!]',
},
Expand Down Expand Up @@ -96,6 +99,21 @@ const defineRamlResource = ({ schema, createTypes }) => {
},
}),

schema.buildObjectType({
name: 'RamlResourceHeaders',
fields: {
header: 'String!',
displayName: 'String',
default: 'String',
pattern: 'String',
type: 'String',
builtinType: 'String',
description: 'String',
required: 'Boolean',
enum: '[String!]',
},
}),

schema.buildObjectType({
name: 'RamlResourceQueryUnionParameter',
fields: {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
function headersToArray(headers) {
if (headers) {
return Object.entries(headers).map(([key, value]) => {
return { header: key, ...value };
});
}

return undefined;
}

export default headersToArray;
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import parametersToArray from '../parameters-to-array.mjs';
import responsesToArray from './responses-to-array.mjs';
import headersToArray from './headers-to-array.mjs';
import codeExamplesToArray from './code-examples-to-array.mjs';
import { examplesToArray } from './examples-to-array.mjs';
import sortProperties from '../sort-properties.mjs';
Expand Down Expand Up @@ -28,6 +29,10 @@ function processMethods({
})
: returnedMethods[method].queryParameters;

returnedMethods[method].headers = headersToArray(
returnedMethods[method].headers
);

returnedMethods[method].responses = responsesToArray(
returnedMethods[method].responses
);
Expand Down
2 changes: 1 addition & 1 deletion websites/api-docs-smoke-test/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"dependencies": {
"@commercetools-docs/gatsby-theme-api-docs": "24.0.3",
"@commercetools-docs/gatsby-theme-docs": "24.1.0",
"@commercetools-docs/rmf-codegen": "13.30.0",
"@commercetools-docs/rmf-codegen": "13.34.0",
"gatsby": "5.12.12",
"gatsby-cli": "5.12.4",
"gatsby-source-filesystem": "5.12.1",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ import { ApiEndpointsForResource } from "/shortcodes"

<ApiEndpointsForResource apiKey="test" resource="/{projectKey}/resource/namespace-action-with-example" />

# /{projectKey}/resource/namespace-action-with-headers

<ApiEndpointsForResource apiKey="test" resource="/{projectKey}/resource/namespace-action-with-headers" />

# /{projectKey}/resource/json-serializable-primitive-type

<ApiEndpointsForResource apiKey="test" resource="/{projectKey}/resource/json-serializable-primitive-type" />
Loading

0 comments on commit f38864b

Please sign in to comment.