我的体式项目的复制可以用任何其他方式完成吗
本文关键字:任何 其他 方式完 项目 复制 我的 | 更新日期: 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_expand
和opt_fields
都记录在开发人员文档的输入/输出选项部分。