How a Relay based Jira field library ?? helped us build the Modernised issue transition experience

How a Relay based Jira field library ?? helped us build the Modernised issue transition experience

We at Atlassian recently announced the modernized Jira Issue-transition experience where the key highlights were a faster performance along with a rich, and consistent field interaction experience to our end users.

In the article below, we cover the approach and the decisions we took to achieve these features, primarily summarising how a bottom up focus on building a contextless and comprehensive Jira Issue field library in Relay helped us build a performant experience much faster.

Introduction

Atlassian offers a range of products, including Jira, Jira Service Management (JSM), Jira Product Discovery (JPD), and Confluence. Many of these products share a similar look and feel, allowing developers to utilize a common component library for creating fields across each application. To streamline this process, we aimed to enhance the reusability of fields beyond merely applying a UI style. Our team focused on modernizing the Issue Transition module, which required us to redevelop these fields. Rather than creating isolated fields, we chose to develop a comprehensive Jira Issue Field Library that promotes greater efficiency and consistency.

Fields are interactive components found in Jira, JSM, JPD, and occasionally in Confluence. For instance, the Comment field is associated with Issues within the Atlassian ecosystem, including Jira, Bitbucket, and Confluence.

Problem statement

As we embarked on the journey to create a modernised issue view, transitioning from the legacy JSP ( Java Server Pages ) to a client-driven React web application, our primary goal was to enhance the user experience for our customers. Consequently, we adopted the standard top-down approach to build the React form application, building the form scaffolding first and then the fields driven by props from the scaffolding/form root.

Then came the modern issue create experience and given it is not tied to any issue, modernising the issue create experience was building another React driven form, thus also building the fields for that form which drives its props from the parent.

Fast forward to 2023, when we set out to build the modernised Issue transition experience , we realised duplication of React components, especially ignoring the observation that, editing a given Field for a given issue essentially means the same irrespective of whether it was done from Issue view or if it was done from Issue transitions. Additionally, we as Atlassian were also moving towards having a uniform and ubiquitous experiences (Uniform means, a given field will look the same irrespective of where it is seen. And ubiquitous means, we are exposing different surfaces to edit a given issue within and beyond Jira).

In 2023, as we embarked on the journey to create a modernised issue transition experience , we recognized the challenge of duplicating React components. We noted that the details and editing behaviour for a specific field for an issue remains consistent, irrespective of the surface ( Issue View, Issue Tables or Issue Transitions ) where the field exists. Furthermore, as we at Atlassian, were moving towards providing a uniform and ubiquitous experience ( "Uniform" signifies that a given field will maintain the same appearance across different contexts, and "ubiquitous" indicates that we are offering various interfaces for editing an issue, both within and beyond Jira ), our existing design might require some work due to the following challenges.

  • Redundancy: Changing a given field’s look and feel would involve repeated changes in multiple places.
  • Tight coupling: As we were expanding the footprint of Jira issue fields, the consumers of these fields (for instance, Confluence which shows Issue preview), also had to be aware of the data and API expectations of the Field (and subsequently changes which might happen to it ), thus tightly coupling the consumer to the Field internals.
  • Performance: We also noticed a lot of performance concerns when using the JSP based Jira Issue Transitions in terms of time taken to do the job.

Solution

Create a comprehensive Jira Issue Field library that mirrors a component library, infused with the unique characteristics of Jira Issue behavior, additionally helping us write a field once and use it many times across experiences like Issue Transitions, Issue View, Issue Tables and so on ( the Write Once Read Many or WORM principle ).

What is a Jira Issue Field Library?

Simply put, a Jira Issue field is a combination of it’s look and it’s behaviour in representing or modifying some attribute of given Jira Issue. For example Assignee field for an Issue X is a User picker which represents the User who is responsible for acting on the issue and modifying it updates the assignee.

A Jira Issue field library is a collection of Jira Issue fields which can be used in any surface dealing with Jira Issue (within the Atlassian ecosystem) Each field is represented by a set of attributes which identifies that field irrespective of where it is consumed. And these attributes help the field determine where to read from and write the data associated with it.

We used a combination the following three concepts to create that Jira Issue field library where each field that is independent, ubiquitous, and highly performant.

  • ARI - The Atlassian Resource Identifier (ARI) is an self-contained identifier that enables the unique identification of content across Atlassian products and services.
  • AGG - Atlassian GraphQL Gateway - AGG is a proxy providing a central GraphQL API over other Atlassian GraphQL or REST APIs.
  • Relay - Relay is a GraphQL client for high performance at any scale. Relay keeps management of data-fetching easy, whether the app has tens, hundreds, or thousands of components. And thanks to Relay’s incremental compiler, it keeps iteration speed fast even as the app grows.

What is meant by ARI being a self-contained identifier?

Self contained means, ARI has the complete information on where to look and refer to the data associated with a given resource entity, be it a Jira Issue Field, a user, a field suggestion and so on.

As mentioned earlier, a given issue field remains and modifies the same data irrespective of whether is used and/or modified in the Issue Search, Issue View, Issue Search results, Issue Transition and/or even Issue fields embedded in Confluence, Atlas and/or Bitbucket.

If we can create a pointer/address to this field, which remains the same irrespective of where the field is consumed, we essentially can make the field a consumer context free entity.

Drawing inspiration from the concept of “pointers” or “pass by reference” in the programming world, where a given pointer represents the same data irrespective of wherever it is passed and used, we define something known as an Atlassian Resource Identifier

An ARI identifies maximum one resource. An ARI contains enough information to resolve the identified resource. It is a combination of multiple pieces of information, all of it together formulates a unique identifier.

For instance the Assignee field for Issue 10001 in John Doe’s tenant would look something this "ari:cloud:jira:john.doe.tenant:issuefieldvalue/10001/assignee"

How do all these fit together to solve the problem?


Using ARI and Relay to build the modern Issue Transitions, developer and user flow
The developer and user flow for an optimised modern Issue Transitions

The diagram above, which will be detailed below, provides a comprehensive overview of the development process and user flow when a user attempts to transition an issue and the corresponding screen is displayed.

Developer flow

As showcased in the diagram, when the developers create components, they declare the data dependencies in the form of relay fragments/queries (1). The relay compiler then aggregates these fragments at the experience root ( issue-transitions in this case ) and optimises the data requirements based on the component data needs (2).

Relay ensures that the data declared by the components is fetched in the most efficient way by deduplicating identical fields, and precomputing information used at runtime, and also caching responses as it sees fit, among other optimisations.

The compiled query is then stored with the code in the repo ( 3 and 4 ), and the CI/CD pipeline actions (5) ensures to sync it with the Query store as a key value pair (6), with the key representing the id of the fragment and value representing the shape of the fragment.

User flow

When a user uses a capability/experience ( say issue transition or issue view ), the request includes the fragment ids ( instead of the actual fragment JSONs ) for the fields it needs info about (1) . The backend GraphQL resolvers then fetch the JSON using this id, in a faster way using server to server communication (2,3,4) and then using the ARI, retrieves the data (5,6) for the requested field(s) in a single round trip ( because ARI has the complete address ), thereby eliminating the need for context lookup and resulting in a quicker turnaround time for the response. This aggregated response is then sent from the resolver to the client (7)

This is optimal due to 2 reasons

  • Using GraphQL relay identifier instead of the whole expected shape as the payload drastically reduces request size and hence the processing delay on the network.
  • ARI ensures that the field data is fetched by the resolvers in a single invocation instead of a waterfall of requests.

??Unlock the potential

As seen above, by revolutionising the development of issue fields and ensuring they remain product-agnostic, we achieved remarkable benefits:

  • ?? Write Once, Read Many (WORM): Similar to utilizing a component library, we now leverage the Field library across various products seamlessly.
  • ?? Bottom-Up Approach: Focus on creating fields first, without the need to consider the consumers. Define a specification, establish a schema contract, and start coding the Field. This approach allows for faster development and the ability to work in parallel.
  • ?? Cross-Product Behaviour Consistency: With this method, the fields will exhibit identical behavior across different products, eliminating isolated bugs! ??
  • ??? Independently Tested and Developed: Much like a component library, the entire Field library is developed and maintained independently at the platform level.
  • </> Faster Development Loop: Simply import the component and pass in the data fragment! Voilà, the Field is integrated!

Revisiting our problems, and how they got solved ??

  • ?? Reduced Redundancy: We successfully developed 70 fields based on this pattern, which was initially implemented solely in the Issue transition module. This initiative has facilitated modernisation throughout Jira, allowing these fields to be utilised in the modern Issue view, Issue Search, and various other areas within Jira. Use of Relay allowed the use of data field fragments in queries for the root experiences, instead of the whole field. This allowed placing these fields within the context of any experience using Relay, ARI, and AGG.
  • ???? Enhanced Dev-loop: This advancement has also enhanced developer performance, since developers can easily import a field, integrate the Field fragment into their parent component, and complete the task!
  • ?? Reduced tight coupling: In the event of any changes, only the Field level fragment in the Field library needs to be updated. All experiences will automatically reflect the updated Field without requiring any code modifications, as Relay manages the schema stitching using Fragments at compile time.
  • ?? Faster User Performance: Use of ARI as a self contained address eliminated waterfall lookups, hence reducing the overall round trip time. Additionally, use of fragment ids in requests also facilitated reducing processing delays.


? The journey of building the comprehensive Jira Issue Field Library stands as a testament to what can be achieved with a dedicated team and a clear vision, also paving way towards building the modern systems of work. It was an intense period of growth and learning, and the experience has left an indelible mark on the team. ???

要查看或添加评论,请登录

社区洞察

其他会员也浏览了