code: func (s *Server) CreateResource(ctx context.Context, request *api.CreateResourceRequest) (*api.CreateResourceResponse, error) {
  	if request.Annotations == nil || request.Annotations.Name == "" {
  		return nil, status.Errorf(codes.InvalidArgument, "Resource must have a name")
  	}
  
  	// finally, validate that Kind is not an emptystring. We know that creating
  	// with Kind as empty string should fail at the store level, but to make
  	// errors clearer, special case this.
  	if request.Kind == "" {
  		return nil, status.Errorf(codes.InvalidArgument, "Resource must belong to an Extension")
  	}
  	r := &api.Resource{
  		ID:          identity.NewID(),
  		Annotations: *request.Annotations,
  		Kind:        request.Kind,
  		Payload:     request.Payload,
  	}
  
  	err := s.store.Update(func(tx store.Tx) error {
  		return store.CreateResource(tx, r)
  	})
  
  	switch err {
  	case store.ErrNoKind:
  		return nil, status.Errorf(codes.InvalidArgument, "Kind %v is not registered", r.Kind)
  	case store.ErrNameConflict:
  		return nil, status.Errorf(
  			codes.AlreadyExists,
  			"A resource with name %v already exists",
  			r.Annotations.Name,
  		)
  	case nil:
  		log.G(ctx).WithFields(logrus.Fields{
  			"resource.Name": r.Annotations.Name,
  			"method":        "CreateResource",
  		}).Debugf("resource created")
  		return &api.CreateResourceResponse{Resource: r}, nil
  	default:
  		return nil, err
  	}
  }
docs: // CreateResource returns a `CreateResourceResponse` after creating a `Resource` based
  // on the provided `CreateResourceRequest.Resource`.
  // - Returns `InvalidArgument` if the `CreateResourceRequest.Resource` is malformed,
  //   or if the config data is too long or contains invalid characters.
  // - Returns an error if the creation fails.