apiaryio / api-blueprint

API Blueprint
https://apiblueprint.org
MIT License
8.64k stars 2.14k forks source link

Extending Data Structures #284

Closed robbinjanssen closed 3 years ago

robbinjanssen commented 8 years ago

Hi, I've got a question/proposal about data structures. Maybe this is more MSON related but I'll start here. To keep data structures nice and tidy, i'd like as little duplicate data as possible, therefor it would be nice if data structures could extend each other.

Assume the following data structure:

# Data Structures

## Project_Link (object) 
+ self: `https://test.api.com/projects/5` (string, required)

## Project1_Get (object)
+ type: `projects` (string, required)
+ id: `5` (string, required)
+ attributes (object, required)
    + number: `PRO-5` (string) - A readable identifier for employees to refer to projects.
+ links (Project_Link, required)

In the links attribute of Project1_Get I re-use the Project_Link object which works great. But suppose I need the following DataStructure as well:

## Project1_Identifier (object)
+ type: `projects` (string, required)
+ id: `5` (string, required)

Now there is duplicate data in my data structures because the Project1_Identifier contains the type and id attribute, but also the Project1_Get contains it. It would be great if I could do the following:

# Data Structures

## Project1_Link (object) 
+ self: `https://test.api.com/projects/5` (string, required)

## Project1_Identifier (object)
+ type: `projects` (string, required)
+ id: `5` (string, required)

## Project1_Get (Project_Identifier) <--- Extend!
+ attributes (object, required)
    + number: `PRO-5` (string) - A readable identifier for employees to refer to projects.
+ links (Project1_Link, required)

In the following example drafter returns errors:

FORMAT: 1A
HOST: https://test.api.com/

# Test API
Hi, welcome to the API!

# Group Projects
Wow, we are using projects!

### Retrieve single project [GET /projects/{id}]
+ Parameters
    + id: `5` (string, required)

+ Response 200 (application/json)
    + Attributes (object)
        + data (Project1_Get, required)

# Data Structures

## Project_Link (object) 
+ self: `https://test.api.com/projects/5` (string, required)

## Project_Identifier (object)
+ type: `projects` (string, required)
+ id: `5` (string, required)

## Project1_Get (Project_Identifier)
+ type: `projects` (string, required)
+ id: `5` (string, required)
+ attributes (object, required)
    + number: `PRO-5` (string) - A readable identifier for employees to refer to projects.
+ links (Project_Link, required)
user@development:/srv/www/docs$ drafter -v
v2.0.0-pre.1
user@development:/srv/www/docs$ drafter --validate docs.md --use-line-num

error: (4)  base type 'Project1_Get' is not defined in the document; line 16, column 11 - line 16, column 40
warning: (8)  unable to find the symbol `Project1_Get` in the list of named types; line 16, column 11 - line 16, column 40
zdne commented 8 years ago

This should be possible. Seems like problem is with the _ in the type name. Renaming Project1_Get to X seemed to work.

Note _ is reserved character per MSON spec – see https://github.com/apiaryio/mson/blob/master/MSON%20Specification.md#6-reserved-characters--keywords

However I believe we are having a bug here in our implementation cc @pksunkara

robbinjanssen commented 8 years ago

You are correct, drafter now approves the markdown using the following example:

FORMAT: 1A
HOST: https://test.api.com/

# Test API
Hi, welcome to the API!

# Group Projects
Wow, we are using projects!

### Retrieve single project [GET /projects/{id}]
+ Parameters
    + id: `5` (string, required)

+ Response 200 (application/json)
    + Attributes (object)
        + data (Project1Get, required)

# Data Structures

## ProjectLink (object) 
+ self: `https://test.api.com/projects/5` (string, required)

## ProjectIdentifier (object)
+ type: `projects` (string, required)
+ id: `5` (string, required)

## Project1Get (ProjectIdentifier)
+ attributes (object, required)
    + number: `PRO-5` (string) - A readable identifier for employees to refer to projects.
+ links (ProjectLink, required)

But indeed I think it's a bug, both aglio and the apiaryio interface are rendering it wrong:

screen shot 2015-11-12 at 11 14 41

Edit: whoops, I see apiaryio is rendering it correct! But it places the type/id at the bottom in this case. My preference would be placing it at the top.

I'll wait before refactoring my docs again ;-)

pksunkara commented 8 years ago

@robbinjanssen If you want them to be at the top, please do something like this:

## Project1Get
+ Include ProjectIdentifier
+ attributes (object, required)
    + number: `PRO-5` (string) - A readable identifier for employees to refer to projects.
+ links (ProjectLink, required)
robbinjanssen commented 8 years ago

@pksunkara cool thanks!

pksunkara commented 8 years ago

A simple example of the bug is as follows:

# GET /projects

+ Response 200 (application/json)
    + Attributes (object)
        + data (B_B, required)

# Data Structures

## A_A
+ a: a

## B_B (A_A)
+ b: b
pksunkara commented 8 years ago

@zdne I think this is related to https://github.com/apiaryio/snowcrash/issues/335. What do you say?