8 no more need this comment about structure
source | link

("├" denotes nesting level in file hierarchy)

(I was having troubles with the code formatting, so I put the code on codepad)

("├" denotes nesting level in file hierarchy)

(I was having troubles with the code formatting, so I put the code on codepad)

7 I feel that having the slash to denote a directory makes this a bit easier to read.
source | link
app/
  ├ code/
  |   ├ Namespace/
  |   |   ├ Custom/
  |   |   |   ├ Api/
  |   |   |   |   ├ CustomRepositoryInterface.php
  |   |   |   |   ├ Data/
  |   |   |   |   |   ├ CustomInterface.php
  |   |   |   |   |   ├ CustomSearchResultsInterface.php
  |   |   |   ├ etc/
  |   |   |   |   ├ di.xml
  |   |   |   |   ├ module.xml
  |   |   |   ├ Model/
  |   |   |   |   ├ Custom.php
  |   |   |   |   ├ CustomRepository.php
  |   |   |   |   ├ ResourceModel/
  |   |   |   |   |   ├ Custom.php
app
  ├ code
  |   ├ Namespace
  |   |   ├ Custom
  |   |   |   ├ Api
  |   |   |   |   ├ CustomRepositoryInterface.php
  |   |   |   |   ├ Data
  |   |   |   |   |   ├ CustomInterface.php
  |   |   |   |   |   ├ CustomSearchResultsInterface.php
  |   |   |   ├ etc
  |   |   |   |   ├ di.xml
  |   |   |   |   ├ module.xml
  |   |   |   ├ Model
  |   |   |   |   ├ Custom.php
  |   |   |   |   ├ CustomRepository.php
  |   |   |   |   ├ ResourceModel
  |   |   |   |   |   ├ Custom.php
app/
  ├ code/
  |   ├ Namespace/
  |   |   ├ Custom/
  |   |   |   ├ Api/
  |   |   |   |   ├ CustomRepositoryInterface.php
  |   |   |   |   ├ Data/
  |   |   |   |   |   ├ CustomInterface.php
  |   |   |   |   |   ├ CustomSearchResultsInterface.php
  |   |   |   ├ etc/
  |   |   |   |   ├ di.xml
  |   |   |   |   ├ module.xml
  |   |   |   ├ Model/
  |   |   |   |   ├ Custom.php
  |   |   |   |   ├ CustomRepository.php
  |   |   |   |   ├ ResourceModel/
  |   |   |   |   |   ├ Custom.php
6 layout style
source | link

(">""├" denotes nesting level in file hierarchy)

app/
>code/  ├ code
>>Namespace/  |   ├ Namespace
>>>Custom/  |   |   ├ Custom
>>>>Api/  |   |   |   ├ Api
>>>>>CustomRepositoryInterface  |   |   |   |   ├ CustomRepositoryInterface.php
>>>>>Data/  |   |   |   |   ├ Data
>>>>>>CustomInterface  |   |   |   |   |   ├ CustomInterface.php
>>>>>>CustomSearchResultsInterface  |   |   |   |   |   ├ CustomSearchResultsInterface.php
>>>>etc/  |   |   |   ├ etc
>>>>>di  |   |   |   |   ├ di.xml
>>>>>module  |   |   |   |   ├ module.xml
>>>>Model/  |   |   |   ├ Model
>>>>>Custom  |   |   |   |   ├ Custom.php
>>>>>CustomRepository  |   |   |   |   ├ CustomRepository.php
>>>>>ResourceModel/  |   |   |   |   ├ ResourceModel
>>>>>>Custom  |   |   |   |   |   ├ Custom.php
  1. Create repository interface (Service Contract) Namespace/Custom/Api/CustomRepositoryInterface.php
    Namespace/Custom/Api/CustomRepositoryInterface.php : http://codepad.org/WognSKnH

  2. Create SearchResultsInterface Namespace/Custom/Api/Data/CustomSearchResultsInterface.php
    Namespace/Custom/Api/Data/CustomSearchResultsInterface.php: http://codepad.org/zcbi8X4Z

  3. Create CustomInterface (Data Container) Namespace/Custom/Api/Data/CustomInterface.php
    Namespace/Custom/Api/Data/CustomInterface.php: http://codepad.org/Ze53eT4o

  4. Create CustomRepository (Concrete Repository ) Namespace/Custom/Model/CustomRepository.php
    Namespace/Custom/Model/CustomRepository.php: http://codepad.org/KNt5QAGZ . This
    This is where the "magic" happens. Through constructor DI, you pass in the resource model/collection factory for your custom module; Regarding the save CRUD method in this Repository, due to your CustomRepositoryInterface, you must pass in a parameter of CustomInterface. Your module's di.xml has a preference to replace an interface of this type with an entity model. The entity model gets passed into the Resource Model and is saved.

  5. Set preference in Namespace/Custom/etc/di.xml
    Namespace/Custom/etc/di.xml: http://codepad.org/KmcoOUeV

  6. Entity model implementing Custom Interface (Data Container) Namespace/Custom/Model/Custom.php
    Namespace/Custom/Model/Custom.php: http://codepad.org/xQiBU7p7 .

  7. Resource model Namespace/Custom/Model/ResourceModel/Custom.php
    Namespace/Custom/Model/ResourceModel/Custom.php: http://codepad.org/IOsxm9qW

(">" denotes nesting level in file hierarchy)

app/
>code/
>>Namespace/
>>>Custom/
>>>>Api/
>>>>>CustomRepositoryInterface.php
>>>>>Data/
>>>>>>CustomInterface.php
>>>>>>CustomSearchResultsInterface.php
>>>>etc/
>>>>>di.xml
>>>>>module.xml
>>>>Model/
>>>>>Custom.php
>>>>>CustomRepository.php
>>>>>ResourceModel/
>>>>>>Custom.php
  1. Create repository interface (Service Contract) Namespace/Custom/Api/CustomRepositoryInterface.php : http://codepad.org/WognSKnH

  2. Create SearchResultsInterface Namespace/Custom/Api/Data/CustomSearchResultsInterface.php: http://codepad.org/zcbi8X4Z

  3. Create CustomInterface (Data Container) Namespace/Custom/Api/Data/CustomInterface.php: http://codepad.org/Ze53eT4o

  4. Create CustomRepository (Concrete Repository ) Namespace/Custom/Model/CustomRepository.php: http://codepad.org/KNt5QAGZ . This is where the "magic" happens. Through constructor DI, you pass in the resource model/collection factory for your custom module; Regarding the save CRUD method in this Repository, due to your CustomRepositoryInterface, you must pass in a parameter of CustomInterface. Your module's di.xml has a preference to replace an interface of this type with an entity model. The entity model gets passed into the Resource Model and is saved.

  5. Set preference in Namespace/Custom/etc/di.xml: http://codepad.org/KmcoOUeV

  6. Entity model implementing Custom Interface (Data Container) Namespace/Custom/Model/Custom.php: http://codepad.org/xQiBU7p7 .

  7. Resource model Namespace/Custom/Model/ResourceModel/Custom.php: http://codepad.org/IOsxm9qW

("├" denotes nesting level in file hierarchy)

app
  ├ code
  |   ├ Namespace
  |   |   ├ Custom
  |   |   |   ├ Api
  |   |   |   |   ├ CustomRepositoryInterface.php
  |   |   |   |   ├ Data
  |   |   |   |   |   ├ CustomInterface.php
  |   |   |   |   |   ├ CustomSearchResultsInterface.php
  |   |   |   ├ etc
  |   |   |   |   ├ di.xml
  |   |   |   |   ├ module.xml
  |   |   |   ├ Model
  |   |   |   |   ├ Custom.php
  |   |   |   |   ├ CustomRepository.php
  |   |   |   |   ├ ResourceModel
  |   |   |   |   |   ├ Custom.php
  1. Create repository interface (Service Contract)
    Namespace/Custom/Api/CustomRepositoryInterface.php : http://codepad.org/WognSKnH

  2. Create SearchResultsInterface
    Namespace/Custom/Api/Data/CustomSearchResultsInterface.php: http://codepad.org/zcbi8X4Z

  3. Create CustomInterface (Data Container)
    Namespace/Custom/Api/Data/CustomInterface.php: http://codepad.org/Ze53eT4o

  4. Create CustomRepository (Concrete Repository )
    Namespace/Custom/Model/CustomRepository.php: http://codepad.org/KNt5QAGZ
    This is where the "magic" happens. Through constructor DI, you pass in the resource model/collection factory for your custom module; Regarding the save CRUD method in this Repository, due to your CustomRepositoryInterface, you must pass in a parameter of CustomInterface. Your module's di.xml has a preference to replace an interface of this type with an entity model. The entity model gets passed into the Resource Model and is saved.

  5. Set preference in
    Namespace/Custom/etc/di.xml: http://codepad.org/KmcoOUeV

  6. Entity model implementing Custom Interface (Data Container)
    Namespace/Custom/Model/Custom.php: http://codepad.org/xQiBU7p7 .

  7. Resource model
    Namespace/Custom/Model/ResourceModel/Custom.php: http://codepad.org/IOsxm9qW

5 Added a note back into list
source | link
4 I ended up including an example of an entity model and resource model...with an explanation on how this ties into the Repository to provide CRUD operations.
source | link
3 Corrected formatting for disclaimer
source | link
2 Included message regarding models/resource models/collections for thoroughness.
source | link
1
source | link