sigs.k8s.io/cluster-api@v1.7.1/docs/book/src/developer/providers/implementers-guide/create_api.md (about)

     1  # Defining your API
     2  
     3  The API generated by Kubebuilder is just a shell. Your actual API will likely have more fields defined on it.
     4  
     5  Kubernetes has a lot of conventions and requirements around API design.
     6  The [Kubebuilder docs][apidesign] have some helpful hints on how to design your types.
     7  
     8  [apidesign]: https://book.kubebuilder.io/cronjob-tutorial/api-design.html#designing-an-api
     9  
    10  Let's take a look at what was generated for us:
    11  
    12  ```go
    13  // MailgunClusterSpec defines the desired state of MailgunCluster
    14  type MailgunClusterSpec struct {
    15  	// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
    16  	// Important: Run "make" to regenerate code after modifying this file
    17  }
    18  
    19  // MailgunClusterStatus defines the observed state of MailgunCluster
    20  type MailgunClusterStatus struct {
    21  	// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
    22  	// Important: Run "make" to regenerate code after modifying this file
    23  }
    24  ```
    25  
    26  Our API is based on Mailgun, so we're going to have some email based fields:
    27  
    28  ```go
    29  type Priority string
    30  
    31  const (
    32  	// PriorityUrgent means do this right away
    33  	PriorityUrgent = Priority("Urgent")
    34  
    35  	// PriorityUrgent means do this immediately
    36  	PriorityExtremelyUrgent = Priority("ExtremelyUrgent")
    37  
    38  	// PriorityBusinessCritical means you absolutely need to do this now
    39  	PriorityBusinessCritical = Priority("BusinessCritical")
    40  )
    41  
    42  // MailgunClusterSpec defines the desired state of MailgunCluster
    43  type MailgunClusterSpec struct {
    44  	// Priority is how quickly you need this cluster
    45  	Priority Priority `json:"priority"`
    46  	// Request is where you ask extra nicely
    47  	Request string `json:"request"`
    48  	// Requester is the email of the person sending the request
    49  	Requester string `json:"requester"`
    50  }
    51  
    52  // MailgunClusterStatus defines the observed state of MailgunCluster
    53  type MailgunClusterStatus struct {
    54  	// MessageID is set to the message ID from Mailgun when our message has been sent
    55  	MessageID *string `json:"response"`
    56  }
    57  ```
    58  
    59  As the deleted comments request, run `make manager manifests` to regenerate some of the generated data files afterwards.
    60  
    61  ```bash
    62  git add .
    63  git commit -m "Added cluster types"
    64  ```
    65  
    66  # Registering APIs in the scheme
    67  
    68  To enable clients to encode and decode your API, your types must be able to be registered within a [scheme].
    69  
    70  [scheme]: https://pkg.go.dev/k8s.io/apimachinery/pkg/runtime#Scheme
    71  
    72  By default, Kubebuilder will provide you with a scheme builder like:
    73  
    74  ```go
    75  import "sigs.k8s.io/controller-runtime/pkg/scheme"
    76  
    77  var (
    78  	// SchemeBuilder is used to add go types to the GroupVersionKind scheme
    79  	SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion}
    80  
    81  	// AddToScheme adds the types in this group-version to the given scheme.
    82  	AddToScheme = SchemeBuilder.AddToScheme
    83  )
    84  ```
    85  
    86  and scheme registration that looks like:
    87  
    88  ```go
    89  func init() {
    90  	SchemeBuilder.Register(&Captain{}, &CaptainList{})
    91  }
    92  ```
    93  
    94  This pattern introduces a dependency on controller-runtime to your API types, which is discouraged for
    95  API packages as it makes it more difficult for consumers of your API to import your API types.
    96  In general, you should minimise the imports within the API folder of your package to allow your API types
    97  to be imported cleanly into other projects.
    98  
    99  To mitigate this, use the following schemebuilder pattern:
   100  
   101  ```go
   102  import "k8s.io/apimachinery/pkg/runtime"
   103  
   104  var (
   105  	// schemeBuilder is used to add go types to the GroupVersionKind scheme.
   106  	schemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)
   107  
   108  	// AddToScheme adds the types in this group-version to the given scheme.
   109  	AddToScheme = schemeBuilder.AddToScheme
   110  
   111  	objectTypes = []runtime.Object{}
   112  )
   113  
   114  func addKnownTypes(scheme *runtime.Scheme) error {
   115  	scheme.AddKnownTypes(GroupVersion, objectTypes...)
   116  	metav1.AddToGroupVersion(scheme, GroupVersion)
   117  	return nil
   118  }
   119  ```
   120  
   121  and register types as below:
   122  
   123  ```go
   124  func init() {
   125  	objectTypes = append(objectTypes, &Captain{}, &CaptainList{})
   126  }
   127  ```
   128  
   129  This pattern reduces the number of dependencies being introduced into the API package within your project.