<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Open Source on Crossref</title><link>https://www.crossref.org/categories/open-source/</link><description>Recent content in Open Source on Crossref</description><generator>Hugo 0.139.4</generator><language>en-us</language><managingEditor>support@crossref.org (Crossref/Cazinc/Benoît Benedetti)</managingEditor><webMaster>support@crossref.org (Crossref/Cazinc/Benoît Benedetti)</webMaster><lastBuildDate>Mon, 18 Mar 2024 00:00:00 +0000</lastBuildDate><atom:link href="https://www.crossref.org/categories/open-source/" rel="self" type="application/rss+xml"/><item><title>Mending Chesterton's fence: open source decision-making</title><link>https://www.crossref.org/blog/mending-chestertons-fence-open-source-decision-making/</link><pubDate>Mon, 18 Mar 2024 00:00:00 +0000</pubDate><author>Joe Wass</author><guid>https://www.crossref.org/blog/mending-chestertons-fence-open-source-decision-making/</guid><description>&lt;p>When each line of code is written it is surrounded by a sea of context: who in the community this is for, what problem we&amp;rsquo;re trying to solve, what technical assumptions we&amp;rsquo;re making, what we already tried but didn&amp;rsquo;t work, how much coffee we&amp;rsquo;ve had today. All of these have an effect on the software we write.&lt;/p>
&lt;p>By the time the next person looks at that code, some of that context will have evaporated. There may be helpful code comments, tests, and specifications to explain how it should behave. But they don&amp;rsquo;t explain the path not taken, and why we didn&amp;rsquo;t take it. Or those occasions where the facts changed, so we changed our mind.&lt;/p>
&lt;p>Some parts of our system are as old as Crossref itself. Whilst our process still involves coffee, it&amp;rsquo;s safe to say that most of our working assumptions have changed, and for good reasons! We have to be very careful when working with our oldest code. We always consider why it was written that way, and what might have changed since. We&amp;rsquo;re always on the look out for &lt;a href="https://thoughtbot.com/blog/chestertons-fence" target="_blank">Chesterton&amp;rsquo;s Fence&lt;/a>!&lt;/p>
&lt;h2 id="leaving-a-trail">Leaving a Trail&lt;/h2>
&lt;p>We&amp;rsquo;re building a new generation of systems at Crossref, and as we go we&amp;rsquo;re being deliberate about supporting the people who will maintain it.&lt;/p>
&lt;p>When our oldest code was written, the software development team all worked in an office with a whiteboard or three, and the code was proprietary. Twenty years later, things are very different. The software development team is spread over 8 timezones. Thanks to &lt;a href="https://openscholarlyinfrastructure.org/" target="_blank">POSI&lt;/a>, all the new code we write is open source, so the next people to read that code might not even be Crossref staff.&lt;/p>
&lt;p>Working increasingly asynchronously, without that whiteboard, we need to record the options, collect evidence, and peer-review them within the team.&lt;/p>
&lt;p>So for the past couple of years the software team has maintained a &lt;a href="https://crossref.gitlab.io/engineering/decision-records/" target="_blank">decision register&lt;/a>. The first decision we recorded was that we should record decisions! Since then we have recorded the significant decisions as they arise. Plus some &lt;a href="https://crossref.gitlab.io/engineering/decision-records/dr-0003/" target="_blank">historical ones&lt;/a>.&lt;/p>
&lt;p>These aren&amp;rsquo;t functional specifications, which describe what the system should do. It&amp;rsquo;s the decisions and trade-offs we made along the way to get to the how. Look out for another blog post about specifications.&lt;/p>
&lt;p>By leaving a trail of explanations as we go, we make it easier for people to understand why code was written, and what has changed. We&amp;rsquo;re writing the story of our new systems. This makes it easier to alter the system in future in response to changes in our community, and the metadata they use.&lt;/p>
&lt;h2 id="difficult-decisions">Difficult Decisions&lt;/h2>
&lt;p>There are some fun challenges to building systems at Crossref. We have a lot of data. Our schema is very diverse, and has a vast amount of domain knowledge embedded in it. It&amp;rsquo;s changed over time to accommodate 20 years of scholarly publishing innovations. Our community is diverse too, from small one-person publishers with a handful of articles, through to large ones that publish millions.&lt;/p>
&lt;p>What might be an obvious decision for a database table with a thousand rows doesn&amp;rsquo;t always translate to a million. When you get to a billion, things change again. An initially sensible choice might not scale. And a scalable solution might look over-engineered if we had millions of DOIs, rather than hundreds of millions.&lt;/p>
&lt;p>The diversity of the data also poses challenges. A very simple feature might get complicated or expensive when it meets the heterogeneity of our metadata and membership. What might scale for journal article or grant metadata might not work for book chapters.&lt;/p>
&lt;p>The big decisions need careful discussion, experimentation, and justification.&lt;/p>
&lt;h2 id="2nf-or-not-2nf">2NF or not 2NF&lt;/h2>
&lt;p>One such recent decision was how we structure our SQL schema for the database that powers our new &amp;lsquo;relationships&amp;rsquo; REST API endpoint, currently in development.&lt;/p>
&lt;p>The data model is simple: we have a table of Relationships which connect pairs of Items. And each Item can have properties (such as a type). The way to model this is straightforward, following conventional &lt;a href="https://en.wikipedia.org/wiki/Database_normalization" target="_blank">normalization rules&lt;/a>:&lt;/p>
&lt;figure>&lt;img src="https://www.crossref.org/images/blog/2024/open-source-decision-making/1.svg"
alt="SQL Tables, normalised" width="100%">
&lt;/figure>
&lt;p>We built the API around it, and all was well.&lt;/p>
&lt;p>We then added a feature which lets you look up relationships based on the properties of the subject or object. For example &amp;ldquo;find citations where the subject is an article and the object is a dataset&amp;rdquo;. This design worked well in our initial testing. We loaded more data into it, and it continued to work well.&lt;/p>
&lt;p>And then, the context changed. Once we tested loading a billion relationships in the database, the performance dropped. The characteristics of the data: size, shape and distribution, reached a point where the database was unable to run queries in a timely way. The PostgreSQL query planner became unpredictable and occasionally produced some quite exciting query plans (to non-technical readers: databases are neither the time nor the place for excitement).&lt;/p>
&lt;p>This is a normal experience in scaling up a system. We expected that something like this would happen at some point, but you don&amp;rsquo;t know when it will happen until you try. We bounced around some ideas and came up with a couple of alternatives. Each made trade-offs around processing time, data storage and query flexibility. The best way to evaluate them was to use real data at a representative scale.&lt;/p>
&lt;p>One of the options was denormalisation. This is a conventional solution to this kind of problem, but was not our first choice as it involves extra machinery to keep the data up-to-date, and more storage. It would not have been the correct solution for a smaller dataset. But we had the evidence that the other two approaches would not scale predictably.&lt;/p>
&lt;figure>&lt;img src="https://www.crossref.org/images/blog/2024/open-source-decision-making/2.svg"
alt="SQL Tables, normalised" width="100%">
&lt;/figure>
&lt;br>
&lt;p>By combining the data into one table, we can serve up API requests much more predictably, and with much better performance. This code is now running with the right performance. Technical readers note that this diagram is simplified. The &lt;a href="https://gitlab.com/crossref/manifold/-/blob/62fc458b280e71c6b6221908fb7824bd3573726f/src/main/resources/db/migration/V1_0_0__initial_schema_creation.sql#L356" target="_blank">real SQL schema&lt;/a> is a little different.&lt;/p>
&lt;p>Without writing this history down, and explaining what we tried, someone might misunderstand the reason for the code and try to simplify it. Decision record &lt;a href="https://crossref.gitlab.io/engineering/decision-records/dr-0500/" target="_blank">DR-0500&lt;/a> guards against that.&lt;/p>
&lt;p>But one day, when the context changes, future developers will be able to come back and modify the code, because they understand why it was like that in the first place.&lt;/p></description></item><item><title>Forming new relationships: contributing to open source</title><link>https://www.crossref.org/blog/forming-new-relationships-contributing-to-open-source/</link><pubDate>Wed, 19 Oct 2022 00:00:00 +0000</pubDate><author>Patrick Vale</author><guid>https://www.crossref.org/blog/forming-new-relationships-contributing-to-open-source/</guid><description>&lt;h2 id="tldr">TL;DR&lt;/h2>
&lt;p>One of the things that makes me glad to work at Crossref is the principles to which we hold ourselves, and the most public and measurable of those must be the &lt;a href="https://openscholarlyinfrastructure.org/" target="_blank">Principles of Open Scholarly Infrastructure&lt;/a>, or POSI, for short. These ambitions lay out how we want to operate - to be open in our governance, in our membership and also in our source code and data. And it&amp;rsquo;s that openness of source code that&amp;rsquo;s the reason for my post today - on 26th September 2022, our first collaboration with the &lt;a href="https://jsonforms.io/" target="_blank">JSON Forms&lt;/a> open-source project was &lt;a href="https://github.com/eclipsesource/jsonforms/releases/tag/v3.0.0" target="_blank">released into the wild&lt;/a>.&lt;/p>
&lt;p>Like most organisations, we depend heavily on open-source software for our operations - the software is universally available, generally high quality and &amp;lsquo;free&amp;rsquo;. And it&amp;rsquo;s easy to take that dependency, and the associated dependency on free time and effort on the part of the maintainers, for granted - but that&amp;rsquo;s not very sustainable. In fact, we believe relying on open-source software without helping to sustain it is an anti-pattern, and this project marks the start of our efforts to make funding open-source software a standard part of our technology budget.&lt;/p>
&lt;p>This isn&amp;rsquo;t the first time we&amp;rsquo;ve &lt;a href="https://github.com/sckott/habanero" target="_blank">supported&lt;/a> or &lt;a href="https://gitlab.com/crossref/rest_api" target="_blank">released&lt;/a> open-source software. Indeed for the past few years, all our new software is open source, and we&amp;rsquo;re in the process of replacing old closed code with new, so that eventually all our code will be open source. But this is the first time we&amp;rsquo;ve contributed extensively to something that isn&amp;rsquo;t focussed primarily on us, and our services. This is a project that we will find very useful, but it is a general purpose tool, and it&amp;rsquo;s already gaining traction in the community.&lt;/p>
&lt;h2 id="background-and-motivations">Background and motivations&lt;/h2>
&lt;p>A while back, I was tasked to do a quick &lt;a href="http://agiledictionary.com/209/spike/" target="_blank">spike&lt;/a> of work on testing the theory that we could use automated form generation tools to bring new interfaces to our users more quickly, and make them easier for &amp;ldquo;people who aren&amp;rsquo;t devs&amp;rdquo; to adapt and manage. We wanted to build a new user interface for registering content, and especially we wanted to make it easier for funders to register the grants they were awarding. As well as being more approachable by a less-technical audience, we also wanted these forms to be accessible (in terms of &lt;a href="https://www.a11yproject.com/" target="_blank">a11y&lt;/a> and users of assistive technology) and localisable - we wanted a solution that would cater to the needs of our rapidly diversifying membership.&lt;/p>
&lt;h2 id="enter-json-schema">Enter JSON Schema&lt;/h2>
&lt;p>We were clear about one side of the puzzle - we knew that we had to look beyond the XML ecosystem upon which much of our existing system is built - and landed on &lt;a href="https://json-schema.org/" target="_blank">JSON Schema&lt;/a>. JSON Schema is a &amp;lsquo;vocabulary that allows you to annotate and validate JSON documents&amp;rsquo;. This means you can describe the shape you expect your data to take, and apply constraints-based validation to that. Which means, in terms of a form library, that you can infer the structure of the form and test that the data entered into it matches what you expect. More than that, you can use that built-in validation to provide error messages to help people get the data right, first time.&lt;/p>
&lt;p>Working backwards from the outcome, the argument for adopting JSON Schema is compelling. It provides a mechanism for checking that data you are handling (for example, receiving input from a form) conforms to the constraints that you declare, but also allows you to tell people up-front, in a human and machine-readable way, what structure and format you will accept. This closed-loop of data annotation and validation gets more appealing when you look at the wide adoption of JSON Schema across languages and libraries. You can pretty much guarantee that for whatever client or server -side technology you are using, there will be a JSON Schema validator for it. Being able to share schemas across your systems (and equally importantly, with third parties) moves JSON schema from &amp;lsquo;just&amp;rsquo; being about data validation, to a key supportive technology.&lt;/p>
&lt;p>Building a form derived from a JSON Schema is an equally attractive prospect. JSON Schema &lt;a href="https://www.jviotti.com/dissertation.pdf" target="_blank">was conceived&lt;/a> during the AjaxWorld conference in 2007 as a &amp;lsquo;JSON-based format for defining the structure of JSON data&amp;rsquo;, and its use as a form-generation tool is relatively new, but there is growing community interest. There is even a &lt;a href="https://github.com/json-schema-org/community/discussions/70" target="_blank">discussion&lt;/a> about how to best create a JSON Schema vocabulary, specifically geared towards addressing some of the needs of form generation users. However, even in its current form, a JSON Schema can be passed to a library, and a very serviceable user interface appears. The devil is always in the detail, and the client-side libraries differ in their abilities to customise areas such as layout (you may not always want your form fields to appear in &lt;strong>exactly&lt;/strong> the same order as they do in your JSON Schema), custom elements (you might want something that wasn&amp;rsquo;t a form input, or that changes based on user input) and localisation. The ability to flexibly customise the appearance and behaviour of the interface was a key factor in our selection of a client-side form generation library.&lt;/p>
&lt;h2 id="choosing-a-library">Choosing a library&lt;/h2>
&lt;p>The other side of the puzzle was less clear - choosing a UI library that would take this JSON Schema, and turn it into a useful, and usable, form. I made the prototype using the venerable &lt;a href="https://github.com/rjsf-team/react-jsonschema-form" target="_blank">React JSON Schema form&lt;/a>. This worked well as a proof of concept, but veered dramatically off our chosen Frontend stack of &lt;a href="https://vuejs.org/" target="_blank">VueJS&lt;/a> and &lt;a href="https://vuetifyjs.com/" target="_blank">Vuetify&lt;/a>, and had some architectural constraints that would limit the scope of customisations we could make to our forms. So I went off looking for libraries that would work with our stack and came up with &lt;a href="https://koumoul-dev.github.io/vuetify-jsonschema-form/latest/" target="_blank">Vuetify JSON Schema Form&lt;/a>, and &lt;a href="https://jsonforms.io/" target="_blank">JSON Forms&lt;/a>.&lt;/p>
&lt;p>Vuetify JSON Schema Form matched our stack perfectly, but made some interesting decisions about the layout of data within the form, and that wouldn&amp;rsquo;t suit our purposes without dramatic modification.&lt;/p>
&lt;p>JSON Forms was an abstracted library, with a core handling the JSON Schema transformation and validation, and separate rendering libraries to handle the form generation. This was great - they had renderers for Angular, React, and even some support for VueJS. But not Vuetify.&lt;/p>
&lt;p>Clearly, we were going to have to make something.&lt;/p>
&lt;p>We made contact with the maintainers of both short-listed libraries to see how we could collaborate in creating a tool that would meet all of our (and hopefully, much of the wider community&amp;rsquo;s) requirements. Both maintainers were very helpful, and we had constructive discussions in both cases. In the end, we decided that the abstracted nature of the JSON Forms project was a better fit for our needs, providing a flexible platform on which we - and others - could extend. We were fortunate to receive funding from the Gordon and Betty Moore Foundation (Grant Agreement #10485) in order to accelerate this work, so we could provide a Grant Registration UI more quickly. We paid a large portion of that funding to the library maintainers, and Crossref contributed a portion of my time on the project. This allowed us to enter into an agreement with &lt;a href="https://eclipsesource.com/" target="_blank">EclipseSource&lt;/a>, the maintainers of JSON Forms, to collaboratively develop the new VueJS and Vuetify renderer library. Stefan Dirix, the lead maintainer, worked with me to build it.&lt;/p>
&lt;p>We didn&amp;rsquo;t forget about Vuetify JSON Schema Form though, and by way of appreciation for their help in the early stages, Crossref made a contribution towards the continued development of that library.&lt;/p>
&lt;h2 id="json-forms---now-with-vuetify">JSON Forms - now with Vuetify&lt;/h2>
&lt;p>Work started on the &lt;a href="https://github.com/eclipsesource/jsonforms-vuetify-renderers" target="_blank">JSON Forms Vuetify renderer set&lt;/a> in September 2021 - Stefan quickly created the first early prototypes of the new form renderers - but then we had a stroke of luck. Our repository received more input from the community. The one that made us sit up and take real notice was the news that someone else had already ported the JSON Forms React renderer set to Vue/Vuetify - and was &lt;a href="https://jsonforms.discourse.group/t/unclear-on-how-to-implement-basic-styling-in-vue2-according-to-github-page/347/5" target="_blank">offering this&lt;/a> as a contribution. &lt;a href="https://github.com/kchobantonov" target="_blank">Krasimir Chobantonov&amp;rsquo;s&lt;/a> fantastic first contribution got &lt;a href="https://github.com/eclipsesource/jsonforms-vuetify-renderers/pull/5" target="_blank">merged in&lt;/a> at the end of the month. This propelled the project forward massively, and was an early validation of the value of working in the open. Needless to say, we were very grateful. Another example of the open source value chain was that Stefan - as the maintainer - could take the time to carefully review and tidy up the incoming code, so what was merged was the product of two great developers.&lt;/p>
&lt;p>Having this great head start meant we could turn our attention to one of the other big areas we wanted to get right - localisation. Traditionally, JSON Schema -generated forms have handled localisation (translation of text and adjustment of date and numerical formats) by wholesale duplication and translation of the schema. This is cumbersome, and doesn&amp;rsquo;t integrate very well with custom error messages, nor external sources of interface messages (think form labels, descriptions, placeholders). So Stefan came up with a proposal, which we accepted, to add complete &lt;a href="https://github.com/eclipsesource/jsonforms/pull/1825" target="_blank">i18n support&lt;/a> to the library. We now have a mechanism by which you can hook up a translation engine of your choice, and JSON forms will use that to lookup messages, before falling back to the validator (also localised!) and finally, the JSON Schema&amp;rsquo;s defaults. This gives much stronger integration and allows the community to plug in their existing localisation methods - no wasted effort.&lt;/p>
&lt;p>Since the localisation addition, we&amp;rsquo;ve been working on fine-tuning the layout engine, making bug fixes, and integrating more closely with the underlying Vuetify library. This allows developers to more easily use the existing Vuetify parameters to change the style and behaviour of their form widgets. Again, no wasted effort. &lt;/p>
&lt;p>We&amp;rsquo;re lucky to have an active community - &lt;a href="https://github.com/kchobantonov" target="_blank">@kchobantonov&lt;/a> continues to make great contributions and push the library forward in unexpected ways - and the library is gaining popularity, with an average of a few hundred downloads per day. &lt;/p>
&lt;p>Some of our funder members have already seen this work in action, and given their feedback on early iterations of the user interface that supports registering grant records. We&amp;rsquo;ll be releasing this publicly very soon to get feedback from members - and then using that feedback to iterate on the grants registration form, and look towards extending it to other record types. &lt;/p>
&lt;h2 id="open-source-positivity">Open source POSItivity&lt;/h2>
&lt;p>A continuous theme throughout this project has been the willingness of people working on these open source projects to be generous with their time and experience. Whether it has been form generation libraries, the &lt;a href="https://json-schema.org/" target="_blank">JSON Schema project&lt;/a> or maintainers of &lt;a href="https://fluent-vue.demivan.me/" target="_blank">localisation plug-ins&lt;/a> - help, advice and encouragement have never been far away. And that&amp;rsquo;s appreciated. But it&amp;rsquo;s not something that we, or any other organisation who relies on the software they produce, should take for granted. Open source software helps everyone who uses it, and there&amp;rsquo;s a real opportunity within our community to make meaningful steps towards supporting its sustainability. Ironically, it&amp;rsquo;s often the most-used general purpose tools that get the least attention. We can change that.&lt;/p>
&lt;h2 id="look-out-for-more">Look out for more&lt;/h2>
&lt;p>Look out for more posts from the &lt;a href="https://www.crossref.org/categories/engineering/">engineering&lt;/a> team, coming soon!&lt;/p>
&lt;h3 id="references">References&lt;/h3>
&lt;p>&lt;a href="https://www.jviotti.com/dissertation.pdf" target="_blank">JSON Binpack: A space-efficient schema-driven and schema-less binary serialization specification based on JSON Schema&lt;/a> (Chapter 3.2.1 History and Relevance)&lt;/p>
&lt;p>&lt;a href="https://web.archive.org/web/20071026190426/http://www.json.com/2007/09/27/json-schema-proposal-collaboration/" target="_blank">https://web.archive.org/web/20071026190426/http://www.json.com/2007/09/27/json-schema-proposal-collaboration/&lt;/a>&lt;/p></description></item></channel></rss>