Core concepts behind Jira Cloud next-gen projects and ongoing changes to our existing APIs

TL;DR

The introduction of next-gen projects at the beginning of 2018 changed some Jira Cloud REST API assumptions and core concepts. As a result some apps experienced unexpected behaviour, few apps stopped working in next-gen projects. We should have communicated this change in behavior ahead of time and moving forward we will do a better job of keeping the developer community up to date on changes that would affect their apps.

App developers and cloud REST API consumers may need to modify their code to support this new model. This blogpost explains core concepts behind next-gen projects and ongoing changes to our existing APIs to allow app developers to fully support next-gen projects.

Why are we implementing next-gen projects? Some background

The goal of next-gen projects is to simplify Jira project configuration experience for administrators and end-users.

  • Next-gen projects simplify the project configuration experience and allow non-jira-admins to create projects and configure them.
  • Project configuration concepts and their application have been simplified without compromising Jira's granular configuration capabilities.

You can find more detailed information from previous blogposts from Hannah and Mythili.

This blog will focus on the technical impact fo Connect App Developers and REST endpoint consumers.

How are next-gen projects different from classic projects?

As mentioned before, there are new concepts in the next-gen model that did not exist in the classic model. Not only that, there were few assumptions that are not valid anymore in next-gen:

  • We introduced the concept of project scoped entities. All configuration entities are bound to a single project and are not sharable with other projects (better to say "not yet"™) which is quite different to the classic model.
  • Project scoped entities cannot use global entities. Example: An Issue Type created for a classic project cannot be used in a next-gen project.
  • Because of project scoped entities, we cannot rely on the name uniqueness of these entities. In fact, it will be pretty common to have multiple projects with different issue types named “Bug”.
  • Next-gen projects no longer have schemes like Issue type screen schemes, Workflow scheme, Issue type schemes, Field configuration scheme, and Screen schemes.

What entities are project scoped?

Notificationscheme, Permissionscheme, Project Roles, Screens, Workflows, Fields, Issue Types and Status. Projects is a special case as we need to know when a project is next-gen or not.

How does this next-gen concept impact existing Apps and REST endpoints?

Classic and next-gen projects have different mental models and constraints. Existing Apps may have to modify their code in order to be able to deal with both worlds.

  • Most of the Apps will require minor or no changes.
  • Some Apps will require major re-design to accomodate to the new model and prepare for a better project configuration experience.

What are the API changes?

  • Read operations on REST endpoints will keep working on both classic and next-gen projects.
    • Read operations return both global and project scoped objects.
    • We are enriching the responses for these entry points so developers are able to disambiguate when entities are project scoped or global.
    • This is a small semantic contract change, but devs need to code around it accordingly. As mentioned before but worth repeating, because next-gen projects don’t share schemes it is perfectly fine to have multiple issue types named "Bug" for different projects apart from the global entity.
  • Mutation operations
    • They work as per contract when applied to classic project configuration objects.
    • ALL existing mutation APIs will fail if trying to operate on project scoped entities. If a REST request is received in an old resource to write an entity that is not a Global Scope, then it will return a status code indicating an error ("400 Bad Request" with a useful message is considered the correct response, but in the interim period some resources might just return 500).
    • We don't have specific APIs for independent projects yet. We will start delivering them as per the Jira Cloud Platform API Public roadmap.

When are we rolling these changes?

  • These changes are already available for project, issue type, notification and permission scheme.
  • We will apply these API changes from v2 onwards.
  • We will keep enriching existing REST endpoints using App usage as priority
  • You should expect more blogposts to give you a clearer picture of next-gen Jira and the Jira Cloud Platform API Public roadmap.

Some key scenarios

As part of first iteration, we are enriching the following endpoints: projects, issue types, project roles and permission schemes.

How do I know whether a project is classic or next-gen?

API

  • GET /rest/api/2/project
  • GET /rest/api/2/project/{projectIdOrKey}

Change

Project details for the specific project will be enriched with a field named style which could be classic or next-gen.

Example response (application/json)

{
  "self": "http://your-domain.atlassian.net/rest/api/2/project/EX",
  "id": "10000",
  "key": "EX",
  "style": "classic" | "next-gen",
   ....
}

How do I know whether an issue type is global or project scoped?

API

  • GET /rest/api/2/issuetype

Change

As we already explained, we are enriching endpoint responses to provide additional scope information for those entities that could be project scoped. The operation for retrieving all issue types will contain additional information that the developer will need to consume to differentiate between scoped issue types vs global ones.

  • Scoped entities have a scope object in the JSON response with a field named type and value "project" that indicates that is project scoped.
  • The scope object contains a project object that represents the project owning this configuration entity. For the time being we are providing the identifier of the project only but we will allow returning additional fields in the future by expanding the response.
  • Global entities don't have a scope object.

Example response (application/json)

[
  {
    "self": "http://your-domain.atlassian.net/rest/api/2/issueType/3",
    "id": "3",
    "description": "A task that needs to be done.",
    "iconUrl": "http://your-domain.atlassian.net//secure/viewavatar?size=xsmall&avatarId=10299&avatarType=issuetype\",",
    "name": "Task",
    "subtask": false,
    "avatarId": 1
  },
  {
    "self": "http://your-domain.atlassian.net/rest/api/2/issueType/1",
    "id": "1",
    "description": "A problem with the software.",
    "iconUrl": "http://your-domain.atlassian.net/secure/viewavatar?size=xsmall&avatarId=10316&avatarType=issuetype\",",
    "name": "Task",
    "subtask": false,
    "avatarId": 10002,
    "scope": {
        "type": "project",
        "project": {
            "id": 11040
        }
    }
  }
]

GET /rest/api/2/project/{projectIdOrKey}?expand=issueTypes returns the project details expanded with the issue types related to that project.

How do I know whether a permission scheme is global or project scoped?

API
  • GET /rest/api/2/permissionscheme

Change

Follows the same pattern as Issue Types.

  • Scoped entities have a scope object in the JSON response with a field named type and value "project" that indicates that is project scoped.
  • The scope object contains a project object that represents the project owning this configuration entity. For the time being we are providing the identifier of the project only but we will allow returning additional fields in the future by expanding the response.
  • Global entities don't have a scope object.

Example response (application/json)

{
  "permissionSchemes": [
    {
      "id": 10000,
      "self": "http://your-domain.atlassian.net/rest/api/3/permissionscheme/10000",
      "name": "Example permission scheme",
      "description": "description",
      "scope": {
        "type": "project",
        "project": {
            "id": 11040
        }
      }
    }
  ]
}

How do I know whether a project role is global or project scoped?

API

  • GET /rest/api/2/role

Change

Follows the same pattern as Issue Types.

  • Scoped entities have a scope object in the JSON response with a field named type and value "project" that indicates that is project scoped.
  • The scope object contains a project object that represents the project owning this configuration entity. For the time being we are providing the identifier of the project only but we will allow returning additional fields in the future by expanding the response.
  • Global entities don't have a scope object.

Example response (application/json)

[
  {
    "self": "http://your-domain.atlassian.net/rest/api/3/project/MKY/role/10360",
    "name": "Developers",
    "id": 10360,
    "description": "A project role that represents developers in a project",
    "actors": [
      ...
    ],
    "scope": {
        "type": "project",
        "project": {
            "id": 11040
        }
      }
  }
]

Could I get the project roles associated to a specific project?

Yes, you don’t need to retrieve the whole list. You can use specific endpoints to get the small subset of roles related to a project.

  • /rest/api/2/project/{projectIdOrKey}/role
  • /rest/api/2/project/{projectIdOrKey}/roledetails

How do I know the statuses for a specific project?

At this moment, we haven't enriched the status endpoint to return all statuses with the scope information; however, there is an API that gives you that information. Check the documentation for further details:

API

  • GET /rest/api/2/project/{projectIdOrKey}/statutes

What about the scope entities that are not described in this blogpost?

In progress. We are committed to providing constant developer communications on the latest updates and changes. With that said, we are currently planning to take the same approach for the remaining scope entities.

Other things to be aware of as an App developer

I hope we provided you with a good overview of the current changes and the impact this has on your apps. Please keep a look out for follow up blog post with more information about the upcoming changes.

So, when should you check your existing code to see if it’s compatible with these changes?

  • You are performing a one-off operation in a project-scoped entity and rely on that for future operations.
    • Let’s say you are asking the customer to create an issue type that you will, later on, link to a newly created project. As we already mentioned, project scoped entities cannot use global entities.
  • You have hard assumptions about name uniqueness of project configuration entities.
    • This is not a valid assumption anymore in next-gen projects and you should code around it accordingly.
  • You are expecting that only admins create new projects and project configuration entities.
    • This is not a valid assumption unless the "Create next-gen projects" global permission is disabled in the instance.

Future work

We will keep working in making next-gen projects awesome and more powerful than classic from the user and developer perspective. Come along on this journey with us and watch the next-gen tag in the Atlassian Developer Community.