func (s *RegistryServer) GetProject(ctx context.Context, req *rpc.GetProjectRequest) (*rpc.Project, error) {
	db, err := s.getStorageClient(ctx)
	if err != nil {
		return nil, status.Error(codes.Unavailable, err.Error())
	}
	defer db.Close()
	name, err := names.ParseProject(req.GetName())
	if err != nil {
		return nil, status.Error(codes.InvalidArgument, err.Error())
	}
	project, err := db.GetProject(ctx, name)
	if err != nil {
		return nil, err
	}
	return project.Message(), nil
}
GetProject handles the corresponding API request.
package registry
import (
	"context"
	"github.com/apigee/registry/rpc"
	"github.com/apigee/registry/server/registry/internal/storage"
	"github.com/apigee/registry/server/registry/internal/storage/models"
	"github.com/apigee/registry/server/registry/names"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
	"google.golang.org/protobuf/types/known/emptypb"
)
func (s *RegistryServer) CreateProject(ctx context.Context, req *rpc.CreateProjectRequest) (*rpc.Project, error) {
	db, err := s.getStorageClient(ctx)
	if err != nil {
		return nil, status.Error(codes.Unavailable, err.Error())
	}
	defer db.Close()
	if req.GetProject() == nil {
		return nil, status.Errorf(codes.InvalidArgument, "invalid project %+v: body must be provided", req.GetProject())
	}
	name := names.Project{ProjectID: req.GetProjectId()}
	if _, err := db.GetProject(ctx, name); err == nil {
		return nil, status.Errorf(codes.AlreadyExists, "project %q already exists", name)
	} else if !isNotFound(err) {
		return nil, err
	}
	if err := name.Validate(); err != nil {
		return nil, status.Error(codes.InvalidArgument, err.Error())
	}
	project := models.NewProject(name, req.GetProject())
	if err := db.SaveProject(ctx, project); err != nil {
		return nil, err
	}
	s.notify(ctx, rpc.Notification_CREATED, name.String())
	return project.Message(), nil
}
func (s *RegistryServer) DeleteProject(ctx context.Context, req *rpc.DeleteProjectRequest) (*emptypb.Empty, error) {
	db, err := s.getStorageClient(ctx)
	if err != nil {
		return nil, status.Error(codes.Unavailable, err.Error())
	}
	defer db.Close()
	name, err := names.ParseProject(req.GetName())
	if err != nil {
		return nil, status.Error(codes.InvalidArgument, err.Error())
	}
	if _, err := db.GetProject(ctx, name); err != nil {
		return nil, err
	}
	if err := db.DeleteProject(ctx, name); err != nil {
		return nil, err
	}
	s.notify(ctx, rpc.Notification_DELETED, name.String())
	return &emptypb.Empty{}, nil
}