{"id":2063,"date":"2015-01-28T11:39:00","date_gmt":"2015-01-28T11:39:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/dotnet\/2015\/01\/28\/net-core-open-source-update\/"},"modified":"2021-09-30T16:10:38","modified_gmt":"2021-09-30T23:10:38","slug":"net-core-open-source-update","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/dotnet\/net-core-open-source-update\/","title":{"rendered":".NET Core Open Source Update"},"content":{"rendered":"<p>Wow. Just wow. I don\u2019t know of a better way to describe my feelings right now. Open source is probably one of the most energizing projects our team has been working on. It\u2019s been a blast so far and the stream of enthusiastic contributors and interactions doesn\u2019t seem to stop any time soon.<\/p>\n<p>In this post, I want to give you a long overdue update on where we are, interesting changes we made, and give an overview of what\u2019s coming next. Read to the end, this is a post you don\u2019t want to miss.<\/p>\n<h2>A good problem to have: Too many forks to display<\/h2>\n<p>In the <a href=\"http:\/\/blogs.msdn.com\/b\/dotnet\/archive\/2014\/11\/20\/one-week-of-open-source.aspx\">first update on open source<\/a> I hinted at the fact that we\u2019ve several teams at Microsoft whose focus is on collecting telemetry. The reason we invest so much in this space is due to the shift from many-year release cycles to quasi real-time delivery. For services, continuous deployment is a very common paradigm today. As a result, the industry has come up with various tools and metrics to measure the health of services. Why is this necessary? Because you need to know when a problem is about to happen, not when it already happened. You want to make small adjustments over time instead of drastic changes every once in a while because it\u2019s much less risky.<\/p>\n<p>Open source is no different from that perspective. We want to know how we\u2019re doing and somewhat predict how this might change over time by recognizing trends. It\u2019s interesting to point out that the metrics aren\u2019t used by management to evaluate my team or even individuals. We use the metrics to evaluate ourselves. (In fact, I believe that evaluating engineers with metrics is a game you can\u2019t win \u2013 engineers are smart little buggers that always find a way to game the system).<\/p>\n<p>One metric totally made my day. When browsing the <a href=\"https:\/\/github.com\/dotnet\/corefx\/graphs\/contributors\">graphs<\/a> of the corefx repo, <a href=\"https:\/\/github.com\/dotnet\/corefx\/network\">GitHub displays the following<\/a>:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2015\/01\/6558.Pic1_.png\"><img decoding=\"async\" style=\"margin-left: auto; margin-right: auto;\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2015\/01\/6558.Pic1_.png\" alt=\"\" border=\"0\" \/><\/a><\/p>\n<p>Indeed we\u2019ve more than <strong>1,000<\/strong> forks! Of course, this a total vanity metric and not indicative of the true number of engagements we have. But we\u2019re still totally humbled by the massive amount of interest we see from the community. And we\u2019re also a tiny bit proud.<\/p>\n<p>But the total number of pull requests is pretty high. In total, we\u2019re approaching <strong>250 pull requests since last November<\/strong> (which includes both, contributors from community as well as Microsoft):<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2015\/01\/3755.Pic2_.png\"><img decoding=\"async\" style=\"margin-left: auto; margin-right: auto;\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2015\/01\/3755.Pic2_.png\" alt=\"\" border=\"0\" \/><\/a><\/p>\n<p>(In case you wonder, I also have a <a href=\"https:\/\/twitter.com\/terrajobst\/status\/559492974917087232\">hypothesis<\/a> what the plateau means).<\/p>\n<p>We\u2019re also thrilled to learn that we\u2019re already outnumbered by the community: the number of community contributions is higher than the number of contributions from us. That\u2019s the reason why open source scales so well \u2013 the community acts as a strong multiplication force.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2015\/01\/3833.Pic3_.png\"><img decoding=\"async\" style=\"margin-left: auto; margin-right: auto;\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2015\/01\/3833.Pic3_.png\" alt=\"\" border=\"0\" \/><\/a><\/p>\n<h2>Real-time communication<\/h2>\n<p>One of the reasons <a href=\"http:\/\/blogs.msdn.com\/b\/dotnet\/archive\/2014\/11\/12\/net-core-is-open-source.aspx\">why we decided to open source .NET Core<\/a> was the ability to build and leverage a stronger ecosystem. Specifically, this is what I wrote last year:<\/p>\n<blockquote><p>To us, open sourcing the stack also means we\u2019re able to engage with customers in real-time. Of course, not every customer wants interact with us that closely. But the ones who do make the stack better for all of us because they provide us with early &amp; steady feedback.<\/p><\/blockquote>\n<p>Of course, the real-time aspect cuts both ways. It\u2019s great if we hear from you in real-time. But how are we responding? If you ever filed a bug on Connect, you may not have had the impression that real-time is a concept that the people outside of the Skype organization have heard of. No offense to my fellow Microsofties; I\u2019m guilty too. It\u2019s incredibly difficult to respond in a timely manner if the worlds of the product team and their active customers are separated by several years.<\/p>\n<p>In order to understand how responsive we are, we collect these two metrics:<\/p>\n<ul>\n<li><strong>How quickly do we respond to an issue?<\/strong> This is the time it takes us to add the first comment.<\/li>\n<li><strong>How quickly do we close an issue?<\/strong> This is the time it takes us to close an issue, regardless of whether it was addressed or discarded.<\/li>\n<\/ul>\n<p>Here are the two graphs:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2015\/01\/1538.Pic4_.png\"><img decoding=\"async\" style=\"margin-left: auto; margin-right: auto;\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2015\/01\/1538.Pic4_.png\" alt=\"\" border=\"0\" \/><\/a><\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2015\/01\/4532.Pic5_.png\"><img decoding=\"async\" style=\"margin-left: auto; margin-right: auto;\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2015\/01\/4532.Pic5_.png\" alt=\"\" border=\"0\" \/><\/a><\/p>\n<p>So far these look pretty good, and are in the realm of real-time collaboration. But there is also some room for improvement: getting a first response shouldn\u2019t take more than a week. We\u2019ll try to improve in this area.<\/p>\n<h2>Open development process<\/h2>\n<p>Part of the reason I share these metrics is to underline that we\u2019re fully committed to an open development process.<\/p>\n<p>But establishing an open development process is more than just sharing metrics and writing blog posts. It\u2019s about rethinking the engineering process for an open source world. In a <a href=\"https:\/\/channel9.msdn.com\/Series\/NET-Framework\/Immo-Landwerth-and-David-Kean-Open-sourcing-the-NET-Framework#time=11m6s\">Channel 9 interview we said<\/a> that we want to be mindful of the new opportunities that open source brings and not simply expose our existing engineering and processes. The reason isn\u2019t so much that we fear giving anything away; it\u2019s about realizing that our existing processes were geared for multi-year release cycles, so not all of them make sense for open source and agile delivery. In order to get there, we generally want to start with less process and only add if it\u2019s necessary.<\/p>\n<p>This requires adapting existing processes and adding some new processes. Let me give you a quick update of which processes we currently have and what tweaks we made.<\/p>\n<h2>Code reviews<\/h2>\n<p>To me, this is by far the most valuable part of collaborative software engineering. Realizing how many mistakes you can prevent by just letting somebody else see your code is a very liberating experience. It\u2019s also the easiest way to spread knowledge across the team. If you haven\u2019t done code reviews, you should start immediately. Once you did them, you\u2019ll ever go back, I promise.<\/p>\n<p>If you look at <a href=\"https:\/\/github.com\/dotnet\/corefx\/pulls\">our GitHub pull requests<\/a>, you\u2019ll find that they aren\u2019t just from the community \u2013 we also leverage pull requests for performing our code reviews. In fact, for parts of the .NET Core that are already on GitHub, there are no internal code reviews \u2013 all code reviews fully happen on GitHub, in public.<\/p>\n<p>This has many advantages:<\/p>\n<ul>\n<li><strong>Sharing expectations<\/strong>. You can understand what feedback we\u2019re providing our peers with, and hence expect contributors to follow, too.<\/li>\n<li><strong>Community participation<\/strong>. Anybody can comment on our pull requests which enables both, you and us, to benefit from the feedback of the entire community.<\/li>\n<li><strong>Our pull request metric looks better<\/strong>. Just kidding. A nice side effect of using pull requests for code reviews is that everything is in one place. There is, tooling wise, no difference between me code reviewing my coworker\u2019s code and reviewing a community pull request. In other words, doing code reviews in public makes our lives easier, not harder.<\/li>\n<\/ul>\n<h2>API reviews<\/h2>\n<p>My team spends a lot of time on API design. This includes making sure an API is very usable, leverages established patterns, can be meaningfully versioned, and is compatible with the previous version.<\/p>\n<p>The way we\u2019ve approached API design is as follows:<\/p>\n<ul>\n<li><strong>Guidance<\/strong>. We\u2019ve documented what constitutes good .NET API design. This information is available publicly as well, via the excellent book <a href=\"http:\/\/amazon.com\/dp\/0321545613\">Framework Design Guidelines<\/a>, written by our architect Krzysztof Cwalina. <a href=\"https:\/\/github.com\/dotnet\/corefx\/wiki\/Framework-Design-Guidelines-Digest\">A super-tiny digest is available on our wiki<\/a>.<\/li>\n<li><strong>Static analysis<\/strong>. We\u2019ve invested into static analysis (formerly known as FxCop) to find common violations, such as incorrect naming or not following established patterns.<\/li>\n<li><strong>API reviews<\/strong>. On top of that, a board of API review experts reviews every single API that goes out. We usually don\u2019t do this on a daily basis, because that wouldn\u2019t efficient. Instead, we review the general API design once a prototype or proposal is available by the team building the API. Depending on the complexity we sometimes review additional iterations. For example, we reviewed the Roslyn APIs many, many times because the number of APIs and concepts is quite large.<\/li>\n<\/ul>\n<p>We\u2019ve found this process to be invaluable because the guidelines themselves are also evolving. For example, when we add new language features and patterns it\u2019s important to come up with a set of good practices that eventually get codified into guidelines. However, it\u2019s rare that the correct guidelines are known at day one; in most cases guidelines are formed based on experience. It\u2019s super helpful to have a somewhat smaller group that is involved in a large number of API reviews because this focuses the attention and allows those folks to discover similarities and patterns.<\/p>\n<p>With open source, we thought hard about how we can incorporate API reviews into an open development process. We\u2019ve <a href=\"https:\/\/github.com\/dotnet\/corefx\/issues\/294\">published a proposal on GitHub<\/a> and based on your feedback <a href=\"http:\/\/blogs.msdn.com\/b\/dotnet\/archive\/2015\/01\/08\/api-review-process-for-net-core.aspx\">put into production<\/a>. The current API review process is now <a href=\"https:\/\/github.com\/dotnet\/corefx\/wiki\/API%20Review%20Process\">documented on our wiki<\/a>.<\/p>\n<p>But having a documented process is just one piece of the puzzle. As many of you pointed out, it\u2019s a huge burden if the reviews are black boxes. After all, the point of having an open development process is to empower the community to be successful with contributing features. This requires infusing the community with the tribal knowledge we have. To do this, we started to record the reviews and <a href=\"https:\/\/channel9.msdn.com\/Series\/NET-Framework\/NET-Core-API-Review-2015-01-14\">upload them to Channel 9<\/a>. We also <a href=\"https:\/\/github.com\/dotnet\/apireviews\/\">upload detailed notes<\/a> and link them to the corresponding parts in the video.<\/p>\n<p>Of course, a complex topic like API design isn\u2019t something that one can learn by simply watching a review. However, watching these reviews will give you a good handle on what aspects we\u2019re looking for and how we approach the problem space.<\/p>\n<p>We\u2019ve also started to document some less documented areas, such as <a href=\"https:\/\/github.com\/dotnet\/corefx\/wiki\/Breaking-Changes\">breaking changes<\/a> and <a href=\"https:\/\/github.com\/dotnet\/corefx\/wiki\/Performance\">performance considerations for the BCL<\/a>. Neither page claims to be complete but we\u2019re curious to get your feedback.<\/p>\n<h2>Contributor license agreements (CLAs)<\/h2>\n<p>Another change we recently did was requiring contributors to sign a <a href=\"http:\/\/en.wikipedia.org\/wiki\/Contributor_License_Agreement\">contributor license agreement (CLA)<\/a>. You can find a copy of the <a href=\"https:\/\/cla.dotnetfoundation.org\/\">CLA on the .NET Foundation<\/a>. The basic idea is making sure that all code contributed to projects in the .NET Foundation can be distributed under their respective licenses.<\/p>\n<p>This is how CLAs are exposed to you:<\/p>\n<ol>\n<li>You submit a pull request<\/li>\n<li>We\u2019ve an automated system to check if the change requires a CLA. For example, trivial typo fixes usually don\u2019t require a CLA. If no CLA is required, the pull request is labelled as <strong>cla-not-required<\/strong> and you\u2019re done.<\/li>\n<li>If the change requires a CLA, the system checks whether you already signed one. If you did, then the pull request is labelled as <strong>cla-signed<\/strong> and you\u2019re done.<\/li>\n<li>If you need to sign a CLA, the bot will label the request as <strong>cla-required<\/strong> and post a comment pointing you to the web site to sign the CLA (fully electronic, no faxing involved). Once you signed a CLA, the pull request is labelled as <strong>cla-signed<\/strong> and you\u2019re done.<\/li>\n<\/ol>\n<p>Moving forward, we\u2019ll only accept pull requests that are labelled as either <strong>cla-not-required<\/strong> or <strong>cla-signed<\/strong>.<\/p>\n<p>It\u2019s worth pointing out that we intend to have a single CLA for the entire .NET Foundation. So once you signed a CLA for any project in the .NET Foundation, you\u2019re done. This means, for example, if you signed a CLA as part of a pull request for <a href=\"https:\/\/github.com\/dotnet\/corefx\">corefx<\/a>, you won\u2019t have to sign another CLA for <a href=\"https:\/\/github.com\/dotnet\/roslyn\">roslyn<\/a>.<\/p>\n<h2>Automated CI system<\/h2>\n<p>We\u2019ve always had an automated build system. The triggers varies between teams, but the most common approach is a daily build in conjunction with a gate that performs some validation before any changes go in. For an open source world, having an internal build system isn\u2019t helping much.<\/p>\n<p>The most common practice on GitHub is to use a continuous integration (CI) system that builds on every push, including pull requests. This way, reviewers on the pull requests don\u2019t have to guess whether the change will pass the build or not \u2013 the registered CI system simply updates the PR accordingly.<\/p>\n<p>GitHub itself doesn\u2019t provide a CI system, it relies on 3rd parties to provide one. Originally, we used <a href=\"http:\/\/www.appveyor.com\/\">AppVeyor<\/a>. It\u2019s free for open source projects and I use it on all my personal projects now. If you haven\u2019t, I highly recommend checking them out. Unfortunately, AppVeyor currently only supports building on Windows. In order to enable our cross-platform work we wanted a system that we can run other systems, especially Linux. So we went ahead and now host our own Jenkins servers to perform the CI service.<\/p>\n<h2>We\u2019re still learning<\/h2>\n<p>Our team is still learning and we believe it\u2019s best to be transparent about it. As David Kean <a href=\"https:\/\/channel9.msdn.com\/Series\/NET-Framework\/Immo-Landwerth-and-David-Kean-Open-sourcing-the-NET-Framework#time=45m37s\">said in our initial open source interview<\/a>:<\/p>\n<blockquote><p>Don\u2019t be afraid to call us on it. If we do something wrong, overstep our boundaries, or do something that you thing we should have done better, call us out on it.<\/p><\/blockquote>\n<p>The earlier you can tell us, the better. So why not share our thinking and learning before we make decisions based on it? Here are a few examples.<\/p>\n<ul>\n<li><strong>Bots talking to bots<\/strong>. When we started to roll our own CI system and added the CLA process, we got a bit trigger happy with using bots, which are essentially automated systems posting comments. This resulted in a flood of comments which caused a lot of noise in the PR discussions and in some cases even dominated the number of comments. Nobody on our side quite liked it, but we also didn&#8217;t think it was the end of the world. But then one customer said:\u00a0&#8220;I am losing a little bit interest because is hard to track real things going on&#8221;. Statements like this are helpful because they make us aware of potential problems. We quickly realized that the number of folks annoyed is actually quite high so we prioritized this work and made our bots a lot less chatty. Instead of C3PO, we now have R2D2. No chitchatting, but few, short and actionable comments.<\/li>\n<li><strong>Using Git<\/strong>. Most of our team members have a lot of experience with using centralized version control, especially Team Foundation Version Control (TFVC). While we also have a set of quite experienced Git users, our team as a whole is still adapting to a decentralized workflow, including usage of topic branches and flowing code between many remotes. <a href=\"https:\/\/twitter.com\/aarnott\">Andrew Arnott<\/a>, who some of you probably know from the <a href=\"https:\/\/channel9.msdn.com\/Shows\/Going+Deep\/Immo-Landwerth-and-Andrew-Arnott-Inside-Immutable-Collections\">Channel 9 interview on immutable collections<\/a>, recently did a Git training for the .NET team. We recorded it and <a href=\"https:\/\/channel9.msdn.com\/Series\/NET-Framework\/Git-Training-for-the-NET-Team\">uploaded it to Channel 9<\/a>. We\u2019d love to hear from you if sharing these kind of videos is interesting to you!<\/li>\n<li><strong>Up-for-grabs<\/strong>. There is an established pattern in the open source community to mark issues in a specific way that the community can query for when they want to find opportunities to jump in. We\u2019ve started to label issues with <a href=\"https:\/\/github.com\/dotnet\/corefx\/issues?q=is%3Aopen+is%3Aissue+label%3Aup-for-grabs\">up-for-grabs<\/a> to indicate bugs or features that we believe are easy to get started with and we don\u2019t currently plan on tackling ourselves. <a href=\"https:\/\/github.com\/dahlbyk\/up-for-grabs.net\/pull\/146\">Thanks to Brendan Forster<\/a>, the corefx project is now also listed on <a href=\"http:\/\/up-for-grabs.net\/#\/tags\/.net\">up-for-grabs.net<\/a>, which is a website devoted to document on how open source projects ask the community for support. Based on some questions Brandon raised, this also <a href=\"https:\/\/github.com\/dotnet\/corefx\/issues\/455\">started a discussion<\/a> of what up-for-grabs actually means. Feel free to jump in and let us know what you think!<\/li>\n<\/ul>\n<p>Are there any other topics you\u2019d interested in? Let us know!<\/p>\n<h2>Library availability<\/h2>\n<p>At the time of the <a href=\"https:\/\/channel9.msdn.com\/Events\/Visual-Studio\/Connect-event-2014\">Connect()<\/a> event, we only had a fraction of the libraries available on GitHub:<\/p>\n<ul>\n<li>System.Collections.Immutable<\/li>\n<li>System.Numerics.Vectors<\/li>\n<li>System.Reflection.Metadata<\/li>\n<li>System.Xml<\/li>\n<\/ul>\n<p>Those four libraries totaled about 145k lines of code. Since then, we\u2019ve added many more libraries which <strong>more than tripled<\/strong> the code size to <strong>now more than half a million lines of code<\/strong>:<\/p>\n<ul>\n<li>Microsoft.Win32.Primitives<\/li>\n<li>Microsoft.Win32.Registry<\/li>\n<li>System.Collections.Concurrent<\/li>\n<li>System.Collections.Immutable<\/li>\n<li>System.Collections.NonGeneric<\/li>\n<li>System.Collections.Specialized<\/li>\n<li>System.Console<\/li>\n<li>System.Diagnostics.FileVersionInfo<\/li>\n<li>System.Diagnostics.Process<\/li>\n<li>System.IO.FileSystem<\/li>\n<li>System.IO.FileSystem.DriveInfo<\/li>\n<li>System.IO.Pipes<\/li>\n<li>System.IO.UnmanagedMemoryStream<\/li>\n<li>System.Linq.Parallel<\/li>\n<li>System.Numerics.Vectors<\/li>\n<li>System.Reflection.Metadata<\/li>\n<li>System.Text.RegularExpressions<\/li>\n<li>System.Threading.Tasks.Dataflow<\/li>\n<li>System.Xml<\/li>\n<\/ul>\n<p>And we\u2019re not even done yet. In fact, we\u2019ve only tackled about 25% of what is to come for .NET Core. A full list is available in an\u00a0<a href=\"https:\/\/msdnshared.blob.core.windows.net\/media\/MSDNBlogsFS\/prod.evol.blogs.msdn.com\/CommunityServer.Components.PostAttachments\/00\/10\/58\/94\/19\/NetCore_OpenSourceUpdate.xlsx\">Excel spread sheet<\/a>.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2015\/01\/6332.Untitled.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/dotnet\/wp-content\/uploads\/sites\/10\/2015\/01\/6332.Untitled.png\" alt=\"\" border=\"0\" \/><\/a><\/p>\n<h2>Summary<\/h2>\n<p>Since November, we\u2019ve made several improvements towards an open development model. Code reviews are in the open and so are <a href=\"https:\/\/channel9.msdn.com\/Series\/NET-Framework\/NET-Core-API-Review-2015-01-14\">API reviews<\/a>. And \u2013 best of all \u2013 we\u2019ve a very active community which already outnumbers the contributions from our team. We couldn\u2019t have hoped for more.<\/p>\n<p>Nonetheless, we\u2019re still at the beginning of our open source journey. We\u2019re heads-down with bringing more .NET Core libraries onto GitHub. On top of that, the runtime team is busy getting the CoreCLR repository ready. You can expect an update on this topic quite soon.<\/p>\n<p>As always, we\u2019d love hearing what you guys think! Let us know via the comments, by posting to <a href=\"http:\/\/forums.dotnetfoundation.org\/\">.NET Foundation Forums<\/a> or by tweeting <a href=\"http:\/\/www.twitter.com\/dotnet\">@dotnet<\/a>.<\/p>\n<p><a href=\"https:\/\/msdnshared.blob.core.windows.net\/media\/MSDNBlogsFS\/prod.evol.blogs.msdn.com\/CommunityServer.Components.PostAttachments\/00\/10\/58\/94\/19\/NetCore_OpenSourceUpdate.xlsx\">NetCore_OpenSourceUpdate.xlsx<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Wow. Just wow. I don\u2019t know of a better way to describe my feelings right now. Open source is probably one of the most energizing projects our team has been working on. It\u2019s been a blast so far and the stream of enthusiastic contributors and interactions doesn\u2019t seem to stop any time soon. In this [&hellip;]<\/p>\n","protected":false},"author":335,"featured_media":58792,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[685],"tags":[30,51,107],"class_list":["post-2063","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-dotnet","tag-announcement","tag-community","tag-open-source"],"acf":[],"blog_post_summary":"<p>Wow. Just wow. I don\u2019t know of a better way to describe my feelings right now. Open source is probably one of the most energizing projects our team has been working on. It\u2019s been a blast so far and the stream of enthusiastic contributors and interactions doesn\u2019t seem to stop any time soon. In this [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/2063","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/users\/335"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/comments?post=2063"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/2063\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media\/58792"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media?parent=2063"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/categories?post=2063"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/tags?post=2063"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}