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

本文关键字:任何 其他 方式完 项目 复制 我的 | 更新日期: 2023-09-27 18:26:06

这是一篇关于Asana的很长的文章,它非常"不灵活"answers"things-left-to--wish-for"API,如果可以以任何其他方式复制项目,那么这就是。

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


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

问题很简单,您可以用Asana API复制一个项目或一组任务吗。Agnoster的回答很简单,这是目前不可能的,但它已经积压了。

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

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

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

我使用这个:"/projects/{project-id}/tasks"来获取任务列表,以便复制这些任务中的每个任务。然后我需要查询每个任务这个"任务/{任务id}/子任务",以获得每个子任务。很直接。

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

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

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

有人看到这里的问题了吗?也就是说,我只从服务器上得到ID和Name,其他什么都没有。任务由注释、受让人、创建日期、截止日期等组成,但以上列表中没有提供这些信息,API端点"任务/{task-id}/子任务"也是如此。

那我们该何去何从呢?好吧,我必须再次查询每个任务,以便获得与实际任务相关的信息。因此,我已经庞大的查询量将几乎翻一番。我的1+50+50查询最终将是1+50+50+50+50。因此,为了通过他们的API复制这个项目,我将稍微超过200个查询,以便将所有信息从第一个项目转移到第二个项目,但等等,还有更多。这只是我实际查询任务所需的查询数量。然后,您必须再添加100个查询,才能在新项目中创建所有新任务。

所以最终的效果是,我想通过Asanas API复制到一个新项目的小项目将花费我大约301个查询才能实现。即使是指示任务是否有子任务的微小更新也会显著减少查询数量。(示例:{"id":1248,"name":"Buy 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;
    }

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

简短的回答是,是的!有一种方法可以控制您返回的数据,它被称为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都记录在开发人员文档的输入/输出选项部分。

相关文章: