我可以用其他任何方式复制体式项目吗?

时间:2014-10-10 10:16:19

标签: c# asana

这是一篇关于Asana的冗长文章,它非常“非常灵活”#34; "事情 - 左到希望" API和如果复制项目可以以任何其他方式完成,那么。

首先,我必须声明我喜欢Asana并通过他们的网站开展工作。所以我不反对它或与它有任何争吵,除了他们的API。如果你还没有,你应该尝试一下,除非你想要/必须通过他们的API写一些针对Asana平台的东西。


本周早些时候我发布了一个关于复制项目的问题,你可以在这里找到: Copy an Asana task/project

问题很简单,您可以使用Asana API复制项目或一组任务吗? Agnoster的答案很简单,现在这是不可能的,但它在积压中。

所以我编写了一些实际复制项目的代码(见下文),然后用所有任务和子任务重新创建整个项目。这是一个相当昂贵的过程,因为你必须分别查询每个任务,这意味着如果我有10个任务,它将是1 + 10个查询。一个查询获取项目包含10个任务的信息,然后我必须查询每个任务以查看它是否包含任何子任务。 如果您在上面列出的每个任务中都有一个子任务,那么您将需要查询其API 1 + 10 * 2次。想象一下,如果你有深层次的嵌套子任务,那么你最终可能最终得到几百甚至一千个查询。

我们目前(在我正在复制的项目中)有50个任务,其中一些只有一个级别的子任务,这意味着大约1 + 50 + 50个请求。因此,他们的API总共有大约101个查询。

现在我发现我从Asana查询的任务缺乏信息。

我使用的是:" / projects / {project-id} / tasks"获取任务列表,以便复制每个任务的每个人。然后我需要查询每个任务" tasks / {task-id} / subasks"为了获得每个子任务。很直接。

现在的问题在于他们的API和我从中获得的回报,我希望手头有更好的解决方案。

如果我查询这个:" / projects / {project-id} / tasks"我得到以下结果:

{
  "data": [
    {
      "id": 1248,
      "name": "Buy catnip"
    },
    {
      "id": 24816,
      "name": "Reflect on role of kittens in society"
    },
    {
      ...
    }
  ]
}

有人在这看到问题吗?即我只从服务器获取ID和名称而不是其他任何事实。任务由笔记,受让人,创建日期,截止日期等组成,但该信息不会在上面的列表中随附,API端点" tasks / {task-id} / subasks"

那么我们离开了哪里?那么我将不得不第二次查询每个任务,以获得与实际任务相关的信息。所以我已经大量的查询将几乎翻倍。我的1 + 50 + 50查询最终将为1 + 50 + 50 + 50 + 50。因此,为了通过他们的API复制这个项目,我将略微超过200个查询,以便从第一个项目获得所有信息到第二个,但是等等,还有更多。这只是我实际查询任务所需的查询数量。然后,您必须添加另外100个查询才能在新项目中创建所有新任务。

所以最终效果是我想通过Asanas API复制到新项目的小项目将花费我大约301个查询来实现。即使是指示任务是否具有子任务的微小更新,也会显着减少查询数量。 (例如:{" id":1248," name":"购买catnip"," hasSubtasks":false})

我的问题很简单,有什么办法可以改善这个吗?我是否错过了一些可以保存查询并提高性能的重要API端点?

以下是我为编写此代码而编写的代码:

    public bool DuplicateAsanaProject(string projectId)
    {
        // Get the current project
        var request = new RestRequest(string.Format("/projects/{0}", projectId), Method.GET);
        request.RequestFormat = DataFormat.Json;

        var asanaProject = Execute<AsanaProjectTemplate>(request);
        if (asanaProject == null)
            return false;

        // Create a new project
        var newAsanaProject = CreateAsanaProjectInTeam(asanaProject.Data.Name, asanaProject.Data.Notes, TeamProductionId);
        // Get all the tasks in the current project
        var tasksInProject = GetAsanaTasksForProject(asanaProject.Data.Id);
        // Reverse all the tasks to get them outputted in the correct order
        tasksInProject.Data.Reverse();
        // Loop through all project tasks
        foreach (var task in tasksInProject.Data)
        {
            // Get the task from the server
            var oldTask = GetAsanaTask(task.Id);
            // Create the new task
            var newTask = CreateAsanaTask(oldTask.Data.Name, oldTask.Data.Notes, newAsanaProject.Data.Id, WorkspaceId);

            // Get the sub-tasks for this task
            var tasksList = GetAsanaTasksForTask(task.Id);
            // If we have some sub-tasks, then create them
            if (tasksList != null && tasksList.Data.Count > 0)
                CreateSubTasksForTask(newTask.Data.Id, tasksList);
        }
        return true;            
    }

    /// <summary>
    /// Create sub-tasks for a specific task
    /// </summary>
    /// <param name="taskId">New task id. This is the task in where the new tasks will be added</param>
    /// <param name="tasks">List all sub-tasks</param>
    public void CreateSubTasksForTask(string taskId, AsanaTasksTemplate tasks)
    {
        // Reverse all the tasks to get them outputted in the correct order
        tasks.Data.Reverse();
        foreach(var task in tasks.Data)
        {
            // Get the task from the server
            var oldTask = GetAsanaTask(task.Id);
            // Create the new task
            var newTask = CreateAsanaSubTask(oldTask.Data.Name, oldTask.Data.Notes, taskId);

            // Get the sub-tasks for this task
            var tasksList = GetAsanaTasksForTask(task.Id);
            // If we have some sub-tasks, then create them
            if (tasksList != null && tasksList.Data.Count > 0)
                CreateSubTasksForTask(newTask.Data.Id, tasksList);
        }
    }

    /// <summary>
    /// Retrieves all sub-tasks for a specific task
    /// </summary>
    /// <param name="taskId"></param>
    /// <returns></returns>
    public AsanaTasksTemplate GetAsanaTasksForTask(string taskId)
    {
        // Get all tasks in the current task
        var request = new RestRequest(string.Format("tasks/{0}/subtasks", taskId), Method.GET);
        request.RequestFormat = DataFormat.Json;

        var result = Execute<AsanaTasksTemplate>(request);
        return result;
    }

1 个答案:

答案 0 :(得分:1)

简短的回答是,是的!有一种方法可以控制您获得的数据,它被称为opt_fields。所以,例如:

GET /projects/ID/tasks?opt_fields=name,notes,created_at,assignee.name,subtasks.name,subtasks.subtasks.name,subtasks.subtasks.subtasks.name

这会回来 - 项目中的所有任务 - 用他们的名字,笔记,创作时间 - 受让人和他们的名字 - 每个嵌套的子任务最多3个级别,只有名称

或者,如果您只是请求该任务,opt_expand=.将为您通常会收到的任务提供所有“标准”字段。

opt_expandopt_fields都记录在开发者文档的Input/Output options部分中。