Referencing Column in Different Schema for One-to-One Relationship in OpenAPI 3.1 - openapi

I'm working with two schemas User and Post. User has fields username, bio, email, and password and Post has fields username, text, and timestamp.
I want to associate field username in Post with field username in User. They will be in a one-to-one relationship.
I have come up with the below specification:
components:
schemas:
Post:
type: object
required:
- username
- text
discriminator:
propertyName: username
mapping:
username: '#/components/schemas/User'
properties:
username:
description: Username of the person who posted
type: string
text:
description: Contents of the post
type: string
timestamp:
description: ISO-8601 timestamp of when the post was made
type: string
format: date-time
User:
type: object
required:
- username
- bio
- email
- password
properties:
username:
description: Username for user
type: string
$ref: '#/components/schemas/Post'
bio:
description: Profile headline
type: string
email:
description: User's email address for notifications and security updates
type: string
password:
description: User's password for login
type: string
Is this correct ?

Related

How to add reference to application/x-www-form-urlencoded request body?

I have built the JSON request below which works fine. But how to provide the $ref if the request media type is application/x-www-form-urlencoded?
For example, you can see the schema Filters which I have created. I want to provide the reference to that in the NewDogRequest.Filter parameter.
openapi: 3.0.2
info:
description: RESTful web services for writing and reading Dogs Data.
version: v1.0
title: Dogs Services
tags:
- name: Dogs
paths:
/dogs:
post:
tags:
- Dogs
summary: Add new dogs data.
description: Use this service when you want to add a new dog.
operationId: addDog
requestBody:
$ref: '#/components/requestBodies/NewDogRequest'
responses:
200:
description: OK
content:
application/json:
schema:
type: string
components:
# ****************** Request Bodies ****************** #
requestBodies:
NewDogRequest:
content:
application/x-www-form-urlencoded:
schema:
type: object
properties:
dogID:
description: >
* Unique dog id.
type: string
filter:
description: >
Specifies the type breed of the dog
type: string
enum:
- German Sheperd
- Husky
- DashHound
default: German Sheperd
# ****************** Schemas ****************** #
schemas:
Filters:
type: string
enum:
- German Sheperd
- Husky
- DashHound
default: German Sheperd
Tried the following, but it didn't work. If you see the image that I have attached the enums are not rendered in the html.
requestBodies:
NewDogRequest:
content:
application/x-www-form-urlencoded:
schema:
type: object
properties:
dogID:
description: >
* Unique dog id.
type: string
filter:
description: >
Specifies the type breed of the dog
$ref: '#/components/schemas/Filters'
Swagger editor image

Where to define reusable subschemas in OpenAPI 3?

I'm working on OpenAPI 3 document. I have schema called CustomerInfo: that has property Address. One of the properties of Address is enum called State. How do I make State a reusable property that can be referenced in other parts of CustomerInfo ?
components:
schemas:
CustomerInfo:
type: object
properties:
Address:
type: object
description: Contains the street, city, zip, and state associated with an address.
properties:
State:
$ref: ''
required:
- Street1
- State
I was thinking about defining a State under definitions: within CustomerInfo, but https://editor.swagger.io/ is throwing exception :
components:
schemas:
CustomerInfo:
type: object
properties:
Address:
type: object
description: Contains the street, city, zip, and state associated with an address.
properties:
State:
$ref: '#/components/schemas/CustomerInfo/definitions/State'
required:
- Street1
- State
definitions:
State: ....
Put the schema of State under components/schemas and it can be referenced.
components:
schemas:
CustomerInfo:
type: object
properties:
Address:
type: object
description: Contains the street, city, zip, and state associated with an address.
properties:
State:
$ref: '#/components/schemas/State'
required:
- State
State:
type: string
enum:
- Alabama
- Alaska
- Arizona

How to use the same definition for an ID parameter and an ID schema property?

I am wondering if there is a way in OpenAPI to describe that the user_id used as a path parameter is the same type of value as the id field of a User object. A benefit of this is reusing the description and example.
openapi: 3.0.1
info:
title: Test API
version: 1.0.0
paths:
/foo/{user_id}:
get:
parameters:
- $ref: '#/components/parameters/user_id'
responses:
'200':
description: A user
content:
application/json:
schema:
$ref: '#/components/schemas/User'
components:
parameters:
user_id:
name: user_id
in: path
required: true
description: the id of a User, from parameters
example: ghijkl
schema:
type: string
schemas:
User:
type: object
properties:
id:
type: string
description: the id of a User, from schemas
example: abcdef
I don't like having to re-define the example and description of the user ID.
You can define a separate schema for the user ID and have the parameter/property schema reference the user ID schema:
components:
parameters:
user_id:
name: user_id
in: path
required: true
schema:
$ref: '#/components/schemas/UserId' # <-------
schemas:
UserId:
type: string
description: The ID of a User
example: abcdef
User:
type: object
properties:
id:
$ref: '#/components/schemas/UserId' # <-------
Swagger Editor and Swagger UI will fetch the parameter example from the schema example, but the parameter description is currently not fetched from the schema description. Feel free to submit an enhancement request.

How do I query MongoDB collection based on related documents (in Doctrine)

I have a few related collections in my Doctrine ODM project…
# Contract.mongodb.yml
Project\Contract\Domain\Contract:
type: document
repositoryClass: Project\SymfonyBundle\ContractBundle\Repository\ContractRepository
collection: Contracts
fields:
id:
type: id
id: true
strategy: UUID
slug:
type: string
length: 128
unique: true
gedmo:
slug:
separator: -
style: default
fields:
- refNo
- name
name:
type: string
refNo:
type: string
purpose:
type: string
budgetAmount:
type: int
budgetCurrency:
type: string
length: 3
startDate:
type: date_immutable
endDate:
type: date_immutable
provider:
type: string
referenceOne:
provider:
targetDocument: Project\Contract\Domain\Provider
cascade:
- persist
- merge
- detach
- refresh
referenceMany:
reports:
targetDocument: Project\Report\Domain\Report
cascade:
- all
# Provider.mongodb.yml
Project\Contract\Domain\Provider:
type: document
repositoryClass: Project\SymfonyBundle\ContractBundle\Repository\ProviderRepository
collection: Providers
fields:
id:
type: id
id: true
strategy: UUID
slug:
type: string
length: 128
unique: true
gedmo:
slug:
separator: -
style: default
fields:
- name
name:
type: string
unique: true
referenceMany:
users:
targetDocument: Project\User\Domain\User
cascade: []
# User.mongodb.yml
Project\User\Domain\User:
type: document
repositoryClass: Project\SymfonyBundle\UserBundle\Repository\UserRepository
collection: Users
fields:
id:
type: id
id: true
strategy: UUID
What I want to do is get the contracts for a given user, but I can't work out how to query the Contracts collection based on a user. Do I need to make 2 queries? 1 to get the user's providers & then a second to query for contracts that link to one of the providers?
If you're able to advise how I do this in the console as well as Doctrine, I'd appreciate the knowledge.
Thanks in advance for your help :o)
You can use the aggregation pipeline and use the $lookup operator to join the document, See - https://docs.mongodb.com/v3.2/reference/operator/aggregation/lookup/
However if this is common, I'd consider re-modeling your documents.

How to set up Swagger with express?

I am using the {swagger-express} library and my code is all in CoffeeScript. For my definition, I have:
app.use swagger.init app,
apis: ['./src/routes.coffee', './src/models.yml']
apiVersion: '0.1.0'
basePath: "http://localhost:#{port}"
info:
title: 'My API'
description: 'A complete listing of all API functions'
swaggerUI: path.join __dirname, 'public'
swaggerURL: '/swagger'
require('./src/routes') app
In routes, I have:
###
* #swagger
* path: /login
* operations:
* - httpMethod: POST
* summary: Login with username and password
* notes: Returns a user based on username
* responseClass: User
* nickname: login
* consumes:
* - text/html
* parameters:
* - name: username
* description: Your username
* paramType: query
* required: true
* dataType: string
* - name: password
* description: Your password
* paramType: query
* required: true
* dataType: string
###
and that works fine. My model.yml file is:
definitions:
User:
properties:
user_id:
type: string
description: Unique ID to represent the user
first_name:
type: string
description: First name of the Uber user.
last_name:
type: string
description: Last name of the Uber user.
email:
type: string
description: Email address of the Uber user
picture:
type: string
description: Image URL of the Uber user.
promo_code:
type: string
description: Promo code of the Uber user.
But that doesn't show up in the api-docs.json. I am trying to define the models in one file and the paths in another. Can that be done?
I don't think it will work because each format is read separately and saved in a hash which is uses the resourcePath as the key.
https://github.com/fliptoo/swagger-express/blob/a5560af936e5398affe36d347af5be2a1bb64fc2/lib/swagger-express/index.js#L27
Any further declaration of the same resourcePath will override the previous declaration.
I tested with an updated yml format with a resourcePath, the name models instead of definitions and a unique id for the model. This made the models show up but none of my other information :/
resourcePath: /login
models:
User:
id: User
properties:
user_id:
type: String
description: Unique ID to represent the user
first_name:
type: String
description: First name of the Uber user.
last_name:
type: String
description: Last name of the Uber user.
email:
type: String
description: Email address of the Uber user
picture:
type: String
description: Image URL of the Uber user.
promo_code:
type: String
description: Promo code of the Uber user.
The example on their github makes it look like this will work but I couldn't make it work.