Skip to content

Commit

Permalink
feat: adds @response decorator
Browse files Browse the repository at this point in the history
  • Loading branch information
matt authored and mschnee committed Feb 6, 2020
1 parent 6eea5e4 commit 9651fe2
Show file tree
Hide file tree
Showing 12 changed files with 692 additions and 119 deletions.
227 changes: 181 additions & 46 deletions docs/site/decorators/Decorators_openapi.md
Original file line number Diff line number Diff line change
Expand Up @@ -427,52 +427,6 @@ export class SomeController {
}
```

#### anyOf, allOf, oneOf, not

The `x-ts-type` extention is also valid as a value in `allOf`, `anyOf`, `oneOf`,
and `not` schema keys.

```ts
@model
class FooModel extends Model {
@property()
foo: string;
}

@model
class BarModel extends Model {
@property()
bar: string;
}

@model
class BazModel extends Model {
@property()
baz: string;
}

class MyController {
@get('/some-value', {
responses: {
'200': {
description: 'returns a union of two values',
content: {
'application/json': {
schema: {
not: {'x-ts-type': BazModel},
allOf: [{'x-ts-type': FooModel}, {'x-ts-type': BarModel}],
},
},
},
},
},
})
getSomeValue() {
return {foo: 'foo', bar: 'bar'};
}
}
```

When the OpenAPI spec is generated, the `xs-ts-type` is mapped to
`{$ref: '#/components/schemas/MyModel'}` and a corresponding schema is added to
`components.schemas.MyModel` of the spec.
Expand Down Expand Up @@ -542,6 +496,187 @@ class MyOtherController {
}
```

### @oas.response

[API document](https://loopback.io/doc/en/lb4/apidocs.openapi-v3.oas.response.html),
[OpenAPI Response Specification](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#response-object)

This decorator lets you easily add response specifications using `Models` from
`@loopback/repository`. The convenience decorator sets the `content-type` to
`application/json`, and the response description to the string value in the
`http-status` module. The models become references through the `x-ts-type`
schema extention.

```ts
@model()
class SuccessModel extends Model {
constructor(err: Partial<SuccessModel>) {
super(err);
}
@property({default: 'Hi there!'})
message: string;
}

class GenericError extends Model {
@property()
message: string;
}

class MyController {
@oas.get('/greet',
@oas.response(200, SuccessModel)
@oas.response(500, GenericError)
greet() {
return new SuccessModel({message: 'Hello, world!'});
}
}
```
```json
{
"paths": {
"/greet": {
"get": {
"responses": {
"200": {
"description": "Ok",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SuccessModel"
}
}
}
},
"500": {
"description": "Internal Server Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/GenericError"
}
}
}
}
}
}
}
}
}
```
#### Using many models
For a given response code, it's possible to have a path that could return one of
many errors. The `@oas.response` decorator lets you pass multiple Models as
arguments. They're combined using an `anyOf` keyword.
```ts
class FooNotFound extends Model {
@property()
message: string;
}

class BarNotFound extends Model {
@property()
message: string;
}

class BazNotFound extends Model {
@property()
message: string;
}

class MyController {
@oas.get('/greet/{foo}/{bar}',
@oas.response(404, FooNotFound, BarNotFound)
@oas.response(404, BazNotFound)
greet() {
return new SuccessModel({message: 'Hello, world!'});
}
}
```
```json
{
"paths": {
"/greet": {
"get": {
"responses": {
"404": {
"description": "Not Found",
"content": {
"application/json": {
"schema": {
"anyOf": [
{"$ref": "#/components/schemas/FooNotFound"},
{"$ref": "#/components/schemas/BarNotFound"},
{"$ref": "#/components/schemas/BazNotFound"}
]
}
}
}
}
}
}
}
}
}
```
#### Using ReferenceObject, ResponseObjects, ContentObjects
You don't have to use loopback `Models` to use this convenience decorator. Valid
ReferenceObjects, ContenObjects, and ResponseObjects are also valid.
```ts
class MyController {

// this is a valid SchemaObject
@oas.get('/schema-object',
@oas.response(200, {
type: 'object',
properties: {
message: 'string'
},
required: 'string'
})
returnFromSchemaObject() {
return {message: 'Hello, world!'};
}

// this is a valid ResponseObject
@oas.get('/response-object',
@oas.response(200, {
content: {
'application/pdf': {
schema: {
type: 'string',
format: 'base64'
}
}
}
})
returnFromResponseObject() {
return {message: 'Hello, world!'};
}

// this is a valid ResponseObject
@oas.get('/reference-object',
@oas.response(200, { $ref: '#/path/to/schema' })
returnFromResponseObject() {
return {message: 'Hello, world!'};
}
}
```
#### Using more options
The `@oas.response` convenience decorator makes some assumptions for you in
order to provide a level of convenience. The `@operation` decorator and the
method convenience decorators let you write a full, complete, and completely
valid `OperationObject`.
### @oas.tags
[API document](https://loopback.io/doc/en/lb4/apidocs.openapi-v3.tags.html),
Expand Down
64 changes: 0 additions & 64 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
"fs-extra": "^8.1.0",
"husky": "^3.1.0",
"lerna": "^3.20.2",
"open-cli": "^5.0.0",
"typescript": "~3.7.5"
},
"scripts": {
Expand All @@ -43,7 +42,7 @@
"tsdocs": "lerna run --scope @loopback/tsdocs build:tsdocs",
"coverage:ci": "node packages/build/bin/run-nyc report --reporter=text-lcov | coveralls",
"precoverage": "npm test",
"coverage": "open-cli coverage/index.html",
"coverage": "open coverage/index.html",
"lint": "npm run prettier:check && npm run eslint && node bin/check-package-locks",
"lint:fix": "npm run eslint:fix && npm run prettier:fix",
"eslint": "node packages/build/bin/run-eslint --report-unused-disable-directives --cache .",
Expand Down
15 changes: 15 additions & 0 deletions packages/openapi-v3/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions packages/openapi-v3/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"@loopback/repository": "^1.19.1",
"@loopback/testlab": "^1.10.3",
"@types/debug": "^4.1.5",
"@types/http-status": "^1.1.2",
"@types/lodash": "^4.14.149",
"@types/node": "^10.17.14"
},
Expand Down
Loading

0 comments on commit 9651fe2

Please sign in to comment.