这是一篇关于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;
}
答案 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_expand
和opt_fields
都记录在开发者文档的Input/Output options部分中。