[{"data":1,"prerenderedAt":1243},["ShallowReactive",2],{"post-\u002Fposts\u002Fwhat-is-a-rest-api":3,"post-author-garywoodfine":852,"post-aside-video-none":6,"\u002Fposts\u002Fwhat-is-a-rest-api-surround":861,"navigation":871,"authors":918,"author-garywoodfine":947,"post-aside-related-candidates":948,"content-section-services":1219,"content-section-products":1222,"content-section-company":1225,"legal-link":1227},{"id":4,"title":5,"aside":6,"author":7,"body":8,"category":831,"date":832,"description":833,"extension":834,"featureImage":835,"meta":838,"navigation":840,"path":841,"seo":842,"sitemap":843,"slug":6,"stem":849,"subtitle":850,"summary":833,"tags":6,"updated":6,"video":6,"__hash__":851},"posts\u002Fposts\u002Fwhat-is-a-rest-api.md","What is a REST API?",null,"garywoodfine",{"type":9,"value":10,"toc":821},"minimark",[11,29,38,41,56,62,65,70,75,78,82,85,89,92,96,99,103,106,110,113,117,124,127,146,149,153,156,246,272,276,282,285,288,291,295,298,301,304,307,310,603,607,627,638,642,645,659,662,665,669,682,750,777,799,809,817],[12,13,14,15,23,24,28],"p",{},"In ",[16,17,22],"a",{"href":18,"rel":19,"title":21},"https:\u002F\u002Fthreenine.blog\u002Fposts\u002Fwhat-is-an-api",[20],"nofollow","What is an API | threenine.io","What is an API"," we introduced and discussed some of the\nbasics concepts and terms associated with what is defined as an API or ",[25,26,27],"em",{},"Application Programming Interface",".",[12,30,31,32,37],{},"A REST API is an API that conforms to the design principles of the ",[25,33,34],{},[25,35,36],{},"Representational State Transfer (REST)","\narchitecture, a software architecture pattern initially created to guide the design and development of the\nWorld Wide Web. REST defines a set of constraints for how the architecture of an Internet-scale\ndistributed hypermedia system, such as the Web, should behave. The REST architectural style emphasises the scalability\nof interactions between components, uniform interfaces, independent deployment of components, and the creation of a\nlayered architecture to facilitate caching of components to reduce user-perceived latency, enforce security, and\nencapsulate legacy systems.",[12,39,40],{},"The REST Architectural style was first defined in 2000 by computer scientist Dr. Roy Fielding in his doctoral\ndissertation, to provides a relatively high level of flexibility and freedom for developers. This flexibility is just\none reason why REST APIs have emerged as a common method for connecting components and applications in a microservices\narchitecture.",[12,42,43,44,49,50,55],{},"In the ",[16,45,48],{"href":46,"rel":47},"https:\u002F\u002Fwww.apitemplatepack.com\u002F",[20],"API Template Pack"," we discussed some high level technical basics in ",[16,51,54],{"href":52,"rel":53},"https:\u002F\u002Fwww.apitemplatepack.com\u002Fdocs\u002Fintroduction\u002Fwhat-is-rest\u002F",[20],"What is REST",",\nbut in this article we will delve a little deeper into the concepts and principles of REST, focusing more on the business\nperspective of REST.",[12,57,14,58,61],{},[16,59,22],{"href":18,"rel":60},[20]," we discussed the concept of an API being an API a\nmechanism  enabling applications or services to access resources within other applications or services. The application\nor service doing the accessing is called the client, and the application or service containing the resource is called\nthe server.",[12,63,64],{},"REST Base API typically follow 6 Design Principles, which are often referred to Architectural Constraints. These\nconstraints are the guiding principles that define the REST architectural style and must be satisfied for an interface\nto be considered RESTful.",[66,67,69],"h3",{"id":68},"rest-api-design-principles","REST API Design Principles",[71,72,74],"h4",{"id":73},"_1-uniform-interface","1 . Uniform interface",[12,76,77],{},"All API requests for the same resource should look the same, no matter where the request comes from. The REST API\nshould ensure that the same piece of data belongs to only one uniform resource identifier (URI). Resources shouldn’t be\ntoo large but should contain every piece of information that the client might need.",[71,79,81],{"id":80},"_2-client-server-decoupling","2. Client-server decoupling",[12,83,84],{},"The client and server applications are completely independent of each other. The only information\nthe client application should know is the URI of the requested resource; it can't interact with the server application\nin any other ways. Similarly, a server application shouldn't modify the client application other than passing it to\nthe requested data via HTTP.",[71,86,88],{"id":87},"_3-stateless","3. Stateless",[12,90,91],{},"REST APIs are stateless, meaning that server does not remember anything about the user who used the API. This means\nthat the server does not store any session data about the client. The client must send all the information that the\nserver needs to fulfil the request. The server will then return a response to the client, but won’t store any session\ndata about the client. This makes REST APIs very fast and scalable.",[71,93,95],{"id":94},"_4-cacheable","4. Cacheable",[12,97,98],{},"Resources should be cacheable on the client or server side. Server responses also need to contain information about\nwhether caching is allowed for the delivered resource. The goal is to improve performance on the client side, while\nincreasing scalability on the server side.",[71,100,102],{"id":101},"_5-layered-system-architecture","5. Layered system architecture",[12,104,105],{},"In REST APIs, the calls and responses go through different layers. As a rule of thumb, don’t assume that the client\nand server applications connect directly to each other. There may be a number of different intermediaries in the\ncommunication loop. REST APIs need to be designed so that neither the client nor the server can tell whether it\ncommunicates with the end application or an intermediary.",[71,107,109],{"id":108},"_6-code-on-demand","6. Code on demand",[12,111,112],{},"REST APIs usually send static resources, but in certain cases, responses can also contain executable code. In these\ncases, the code should only run on-demand.",[66,114,116],{"id":115},"rest-api-resources","REST API Resources",[12,118,119,120,123],{},"The key abstraction of information in REST is a ",[25,121,122],{},"resource",".  A resource is a conceptual mapping to a set of entities,\nnot the entity that corresponds to the mapping at any particular point in time.",[12,125,126],{},"Any information that can be named can be a resource:",[128,129,130,134,137,140,143],"ul",{},[131,132,133],"li",{},"document",[131,135,136],{},"image",[131,138,139],{},"a temporal service (e.g. \"today's weather in London\")",[131,141,142],{},"a collection of other resources",[131,144,145],{},"a non-virtual object or a digital representation of anything in the real world  (e.g. a person)",[12,147,148],{},"In other words, any concept that might be the target of a hypertext reference must fit within the definition of a resource,\nand every resource should have a unique identifier. In the case of HTTP, URIs are used to identify resources.",[66,150,152],{"id":151},"rest-api-methods","REST API Methods",[12,154,155],{},"There are typically five methods that are commonly used in a REST-based Architecture:",[157,158,159,172],"table",{},[160,161,162],"thead",{},[163,164,165,169],"tr",{},[166,167,168],"th",{},"Method",[166,170,171],{},"Description",[173,174,175,187,197,207,216,226,236],"tbody",{},[163,176,177,184],{},[178,179,180],"td",{},[181,182,183],"strong",{},"GET",[178,185,186],{},"Retrieves a representation of the resource at the specified URI.",[163,188,189,194],{},[178,190,191],{},[181,192,193],{},"POST",[178,195,196],{},"Creates a new resource at the specified URI.",[163,198,199,204],{},[178,200,201],{},[181,202,203],{},"PUT",[178,205,206],{},"Updates the capabilities of the resource at the specified URI.",[163,208,209,214],{},[178,210,211],{},[181,212,213],{},"PATCH",[178,215,206],{},[163,217,218,223],{},[178,219,220],{},[181,221,222],{},"DELETE",[178,224,225],{},"Deletes the resource at the specified URI.",[163,227,228,233],{},[178,229,230],{},[181,231,232],{},"HEAD",[178,234,235],{},"Retrieves the headers of the resource at the specified URI.",[163,237,238,243],{},[178,239,240],{},[181,241,242],{},"OPTIONS",[178,244,245],{},"Retrieves the options available for the resource at the specified URI.",[247,248,249,267],"content-warning",{},[250,251,253,256,262],"template",{"v-slot:text":252},"",[12,254,255],{},"Many may intuitively assume that the HTTP method names are used to indicate CRUD based operations, but this is certainly\nnot the case.  The idea of an HTTP resource is very abstract and is not really directly related to database design at all.",[12,257,258,259],{},"The HTTP methods are used to indicate the desired action to be performed on the resource. ",[25,260,261],{},"The HTTP methods are not directly related to CRUD operations.",[12,263,264],{},[181,265,266],{},"CRUD operations are not a requirement for a REST based API",[250,268,269],{"v-slot:title":252},[12,270,271],{},"REST is not about CRUD",[66,273,275],{"id":274},"when-to-use-rest","When to use REST",[277,278,279],"content-quote",{},[12,280,281],{},"The REST interface is designed to be efficient for large-grain hypermedia data transfer, optimising for the common case\nof the Web, but resulting in an interface that is not optimal for other forms of architectural interaction.",[12,283,284],{},"REST API's are great architectural pattern to use when interaction level requires course-grained resources over a HTTP based network.\nThis is common for APIs exposed over the internet that are consumed by web applications, mobile applications or other\ninternet connected devices, where the network latency is high and the bandwidth is low.",[12,286,287],{},"REST is defacto standard for exposing APIs over the internet and is the most common architectural pattern used for\nexposing APIs over the internet. A large majority of organisations have adopted REST as their standard for exposing\nAPIs to develop customer and partner facing Web APIs, and also for exposing internal APIs to support their internal\napplications.",[12,289,290],{},"This is because REST APIs are easy to understand, relatively easy to implement, and easy to consume. REST APIs are also very\nflexible and can be used to expose a wide variety of data and functionality. REST APIs are also very scalable and\nperformant, and can be used to support a large number of clients.  However, unfortunately not all developers or\norganisations understand the principles of REST which often misuse the term REST to describe any HTTP based API, and worse\nincorrectly implement their APIs often leading to poor performance and scalability issues, and what is called a REST Anti-Patterns.",[66,292,294],{"id":293},"what-is-hateoas","What is HATEOAS ?",[12,296,297],{},"The term HATEOAS stands for the phrase Hypermedia As The Engine Of Application State, and it is often mentioned\nsynonymously with REST, and is also considered by purists as one of the key principles of REST.",[12,299,300],{},"The main idea of HATEOAS is that a client interacts with a RESTful API entirely through dynamically provided hypermedia\nlinks, which means that the information provided by the server includes links to the actions that can be taken next.\nThis allows for a more flexible and decoupled system, as clients do not need to have hard-coded knowledge of the API's\nstructure beyond an initial entry point.",[12,302,303],{},"In simple terms, with HATEOAS, a client navigates the API through links provided by the server,\nmuch like how you navigate a website by clicking on links. This makes the client less dependent on the URL structure of\nthe API.",[12,305,306],{},"It was envisioned when HATEOAS was fully implemented within API that the Response object of an API would provide all additional\nendpoints that were available to interact further with a resource.",[12,308,309],{},"The following is an example of how a JSON response might look with HATEOAS in place, the links array provides URIs to\nvarious actions related to the resource, such as updating, deleting, or navigating to a related resource.",[311,312,316],"pre",{"className":313,"code":314,"language":315,"meta":252,"style":252},"language-json shiki shiki-themes material-theme-lighter monokai monokai monokai","{\n  \"id\": 1,\n  \"name\": \"Sample Resource\",\n  \"links\": [\n    {\n      \"rel\": \"self\",\n      \"href\": \"\u002Fresources\u002F1\"\n    },\n    {\n      \"rel\": \"update\",\n      \"href\": \"\u002Fresources\u002F1\u002Fupdate\"\n    },\n    {\n      \"rel\": \"delete\",\n      \"href\": \"\u002Fresources\u002F1\u002Fdelete\"\n    },\n    {\n      \"rel\": \"related-resource\",\n      \"href\": \"\u002Frelated-resources\u002F5\"\n    }\n  ]\n}\n\n","json",[317,318,319,328,352,376,391,397,420,440,446,451,471,489,494,499,519,537,542,547,567,585,591,597],"code",{"__ignoreMap":252},[320,321,324],"span",{"class":322,"line":323},"line",1,[320,325,327],{"class":326},"s8B1f","{\n",[320,329,331,335,339,342,345,349],{"class":322,"line":330},2,[320,332,334],{"class":333},"siAel","  \"",[320,336,338],{"class":337},"sI02Y","id",[320,340,341],{"class":333},"\"",[320,343,344],{"class":326},":",[320,346,348],{"class":347},"so6kZ"," 1",[320,350,351],{"class":326},",\n",[320,353,355,357,360,362,364,368,372,374],{"class":322,"line":354},3,[320,356,334],{"class":333},[320,358,359],{"class":337},"name",[320,361,341],{"class":333},[320,363,344],{"class":326},[320,365,367],{"class":366},"slCjU"," \"",[320,369,371],{"class":370},"sy4__","Sample Resource",[320,373,341],{"class":366},[320,375,351],{"class":326},[320,377,379,381,384,386,388],{"class":322,"line":378},4,[320,380,334],{"class":333},[320,382,383],{"class":337},"links",[320,385,341],{"class":333},[320,387,344],{"class":326},[320,389,390],{"class":326}," [\n",[320,392,394],{"class":322,"line":393},5,[320,395,396],{"class":326},"    {\n",[320,398,400,403,407,409,411,413,416,418],{"class":322,"line":399},6,[320,401,402],{"class":333},"      \"",[320,404,406],{"class":405},"soY9U","rel",[320,408,341],{"class":333},[320,410,344],{"class":326},[320,412,367],{"class":366},[320,414,415],{"class":370},"self",[320,417,341],{"class":366},[320,419,351],{"class":326},[320,421,423,425,428,430,432,434,437],{"class":322,"line":422},7,[320,424,402],{"class":333},[320,426,427],{"class":405},"href",[320,429,341],{"class":333},[320,431,344],{"class":326},[320,433,367],{"class":366},[320,435,436],{"class":370},"\u002Fresources\u002F1",[320,438,439],{"class":366},"\"\n",[320,441,443],{"class":322,"line":442},8,[320,444,445],{"class":326},"    },\n",[320,447,449],{"class":322,"line":448},9,[320,450,396],{"class":326},[320,452,454,456,458,460,462,464,467,469],{"class":322,"line":453},10,[320,455,402],{"class":333},[320,457,406],{"class":405},[320,459,341],{"class":333},[320,461,344],{"class":326},[320,463,367],{"class":366},[320,465,466],{"class":370},"update",[320,468,341],{"class":366},[320,470,351],{"class":326},[320,472,474,476,478,480,482,484,487],{"class":322,"line":473},11,[320,475,402],{"class":333},[320,477,427],{"class":405},[320,479,341],{"class":333},[320,481,344],{"class":326},[320,483,367],{"class":366},[320,485,486],{"class":370},"\u002Fresources\u002F1\u002Fupdate",[320,488,439],{"class":366},[320,490,492],{"class":322,"line":491},12,[320,493,445],{"class":326},[320,495,497],{"class":322,"line":496},13,[320,498,396],{"class":326},[320,500,502,504,506,508,510,512,515,517],{"class":322,"line":501},14,[320,503,402],{"class":333},[320,505,406],{"class":405},[320,507,341],{"class":333},[320,509,344],{"class":326},[320,511,367],{"class":366},[320,513,514],{"class":370},"delete",[320,516,341],{"class":366},[320,518,351],{"class":326},[320,520,522,524,526,528,530,532,535],{"class":322,"line":521},15,[320,523,402],{"class":333},[320,525,427],{"class":405},[320,527,341],{"class":333},[320,529,344],{"class":326},[320,531,367],{"class":366},[320,533,534],{"class":370},"\u002Fresources\u002F1\u002Fdelete",[320,536,439],{"class":366},[320,538,540],{"class":322,"line":539},16,[320,541,445],{"class":326},[320,543,545],{"class":322,"line":544},17,[320,546,396],{"class":326},[320,548,550,552,554,556,558,560,563,565],{"class":322,"line":549},18,[320,551,402],{"class":333},[320,553,406],{"class":405},[320,555,341],{"class":333},[320,557,344],{"class":326},[320,559,367],{"class":366},[320,561,562],{"class":370},"related-resource",[320,564,341],{"class":366},[320,566,351],{"class":326},[320,568,570,572,574,576,578,580,583],{"class":322,"line":569},19,[320,571,402],{"class":333},[320,573,427],{"class":405},[320,575,341],{"class":333},[320,577,344],{"class":326},[320,579,367],{"class":366},[320,581,582],{"class":370},"\u002Frelated-resources\u002F5",[320,584,439],{"class":366},[320,586,588],{"class":322,"line":587},20,[320,589,590],{"class":326},"    }\n",[320,592,594],{"class":322,"line":593},21,[320,595,596],{"class":326},"  ]\n",[320,598,600],{"class":322,"line":599},22,[320,601,602],{"class":326},"}\n",[66,604,606],{"id":605},"benefits-of-hateoas","Benefits of HATEOAS",[128,608,609,615,621],{},[131,610,611,614],{},[181,612,613],{},"Decoupling:"," Clients are less dependent on the server's URL structure.",[131,616,617,620],{},[181,618,619],{},"Discoverability:"," The API is more self-descriptive and discoverable since clients can explore available actions dynamically through links.",[131,622,623,626],{},[181,624,625],{},"Evolution:"," The server can evolve more easily without breaking clients, since the relevant links are provided dynamically.",[628,629,630,633],"quote",{},[12,631,632],{},"software design on the scale of decades: every detail is intended to promote software longevity and independent evolution. Many of the constraints are directly opposed to short-term efficiency. Unfortunately, people are fairly good at short-term design, and usually awful at long-term design",[250,634,635],{"v-slot:citation":252},[12,636,637],{},"Roy Fielding",[66,639,641],{"id":640},"problems-of-hateoas","Problems of HATEOAS",[12,643,644],{},"For the most HATEOAS for API's just dont work in practice, and the reality from my experience it is almost never implemented.\nIn fact, I have never seen it implemented in any API's I've integrated with and even API's I've worked on. There are a\nfew reasons for this:",[128,646,647,650,653,656],{},[131,648,649],{},"There are very few good tools to create a REST API using this style",[131,651,652],{},"There are no clients widely used to consume these types of APIs",[131,654,655],{},"Most software teams just never get round to implementing it",[131,657,658],{},"Most teams just rely on documentation to explain how their API's operate.",[12,660,661],{},"For the most part, this renders the whole concept of HATEOAS useless. The concepts of loose coupling and evolvability by\ncreating a generic interface are voided when most clients don’t use it.",[12,663,664],{},"Over the years I have read many books and blog posts all discussing HATEOAS and listing the benefits of it and how\nsupposedly many organisations implement it in their REST API, but I've never actually seen any evidence of this.",[66,666,668],{"id":667},"resource-oriented-apis","Resource Oriented API's",[12,670,671,672,677,678,681],{},"According to REST API purist perspective, there are actually very few if any pure REST API, primarily because there\nnone that actually implement HATEOAS. For the most part, in my experience, there are only really ",[181,673,674],{},[25,675,676],{},"REST inspired API's",",\nor what are more commonly known as ",[181,679,680],{},"Resource-oriented"," API's, which are API's that for the most partially implement\nthe typical REST based resource endpoints:",[157,683,684,692],{},[160,685,686],{},[163,687,688,690],{},[166,689,168],{},[166,691,171],{},[173,693,694,702,710,718,726,734,742],{},[163,695,696,700],{},[178,697,698],{},[181,699,183],{},[178,701,186],{},[163,703,704,708],{},[178,705,706],{},[181,707,193],{},[178,709,196],{},[163,711,712,716],{},[178,713,714],{},[181,715,203],{},[178,717,206],{},[163,719,720,724],{},[178,721,722],{},[181,723,213],{},[178,725,206],{},[163,727,728,732],{},[178,729,730],{},[181,731,222],{},[178,733,225],{},[163,735,736,740],{},[178,737,738],{},[181,739,232],{},[178,741,235],{},[163,743,744,748],{},[178,745,746],{},[181,747,242],{},[178,749,245],{},[12,751,752,753,755,756,758,759,761,762,764,765,768,769,772,773,776],{},"In most cases it may be possible that API's may only implement a mixed degree of these types of endpoints for a resource.\nFor Instance,  on some resources you may only have access too ",[317,754,183],{}," & ",[317,757,193],{},", other resources may only ever have a ",[317,760,183],{},"\nothers will have multiple ",[317,763,183],{}," with a myriad of differing names i.e. ",[317,766,767],{},"GetLatestItem"," ,  ",[317,770,771],{},"GetAllItems",",  ",[317,774,775],{},"GetItemByDate"," etc\nOne could argue that these endpoints have been badly designed or poor, but I can tell you from a number of organisations\nI've had the opportunity to work with this approach is more common than most care to admit.",[277,778,779,790],{},[12,780,781,782,785,786,789],{},"resource-oriented APIs rely on the idea of ",[25,783,784],{},"resources"," which are the key concepts we store and interact with standardising\nthe ",[25,787,788],{},"things"," that the API manages",[250,791,792],{"v-slot:citation":252},[12,793,794],{},[16,795,798],{"href":796,"rel":797},"https:\u002F\u002Fgarywoodfine.com\u002Freviews\u002Fbooks\u002Fapi-design-patterns",[20],"JJ Geewax - API Design Patterns",[12,800,801,802,808],{},"One of best API's I've worked with and appreciate is the ",[16,803,807],{"href":804,"rel":805,"title":806},"https:\u002F\u002Fdocs.stripe.com\u002Fapi",[20],"stripe api","Stripe API",", for a number\nof reasons, but mostly because it is a well documented and consistent.  Working with API, you'll also notice that there is\nno HATEOAS implementation, but it uses resource-oriented endpoints to enable interaction.",[810,811,812],"top-tip",{},[250,813,814],{"v-slot:message":252},[12,815,816],{},"Resource-oriented APIs are a way of designing APIs to reduce complexity by relying on a standard set of actions\ncalled, methods, across a limited set of things, called resources.",[818,819,820],"style",{},"html pre.shiki code .s8B1f, html code.shiki .s8B1f{--shiki-light:#39ADB5;--shiki-default:#F8F8F2;--shiki-dark:#F8F8F2;--shiki-sepia:#F8F8F2}html pre.shiki code .siAel, html code.shiki .siAel{--shiki-light:#39ADB5;--shiki-light-font-style:inherit;--shiki-default:#66D9EF;--shiki-default-font-style:italic;--shiki-dark:#66D9EF;--shiki-dark-font-style:italic;--shiki-sepia:#66D9EF;--shiki-sepia-font-style:italic}html pre.shiki code .sI02Y, html code.shiki .sI02Y{--shiki-light:#9C3EDA;--shiki-light-font-style:inherit;--shiki-default:#66D9EF;--shiki-default-font-style:italic;--shiki-dark:#66D9EF;--shiki-dark-font-style:italic;--shiki-sepia:#66D9EF;--shiki-sepia-font-style:italic}html pre.shiki code .so6kZ, html code.shiki .so6kZ{--shiki-light:#F76D47;--shiki-default:#AE81FF;--shiki-dark:#AE81FF;--shiki-sepia:#AE81FF}html pre.shiki code .slCjU, html code.shiki .slCjU{--shiki-light:#39ADB5;--shiki-default:#CFCFC2;--shiki-dark:#CFCFC2;--shiki-sepia:#CFCFC2}html pre.shiki code .sy4__, html code.shiki .sy4__{--shiki-light:#91B859;--shiki-default:#CFCFC2;--shiki-dark:#CFCFC2;--shiki-sepia:#CFCFC2}html pre.shiki code .soY9U, html code.shiki .soY9U{--shiki-light:#E2931D;--shiki-light-font-style:inherit;--shiki-default:#66D9EF;--shiki-default-font-style:italic;--shiki-dark:#66D9EF;--shiki-dark-font-style:italic;--shiki-sepia:#66D9EF;--shiki-sepia-font-style:italic}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html.sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}",{"title":252,"searchDepth":330,"depth":330,"links":822},[823,824,825,826,827,828,829,830],{"id":68,"depth":354,"text":69},{"id":115,"depth":354,"text":116},{"id":151,"depth":354,"text":152},{"id":274,"depth":354,"text":275},{"id":293,"depth":354,"text":294},{"id":605,"depth":354,"text":606},{"id":640,"depth":354,"text":641},{"id":667,"depth":354,"text":668},"development","2023-06-05","A REST API is an API that conforms to the design principles of the REST, or representational state transfer architectural style. For this reason, REST APIs are sometimes referred to RESTful APIs.","md",{"url":836,"title":837},"v1719908247\u002Fapi_f3f1mh","What is an API?",{"publishDateTime":839},"2023-06-05:17:30",true,"\u002Fposts\u002Fwhat-is-a-rest-api",{"title":5,"description":833},{"loc":841,"lastmod":832,"changefreq":844,"priority":845,"images":846},"monthly",0.8,[847],{"loc":848},"https:\u002F\u002Fres.cloudinary.com\u002Fthreenine-co-uk\u002Fimage\u002Fupload\u002Ff_jpg,w_1200\u002Fv1719908247\u002Fapi_f3f1mh","posts\u002Fwhat-is-a-rest-api","A flexible, lightweight approach to connecting and integrating applications.","qVf88CpRTqypPkBdwBIm_USTpWKRYgQDWS0PErt1AwU",{"name":853,"to":854,"avatar":855,"sameAs":856},"Gary Woodfine","https:\u002F\u002Fgarywoodfine.com","garywoodfine_tlccjw",[857,858,859,860],"https:\u002F\u002Fgithub.com\u002Fgarywoodfine","https:\u002F\u002Fwww.youtube.com\u002F@Threenineio","https:\u002F\u002Fnjump.me\u002Fnpub1a3jz7w9laar2k77dkkh2rhxunr9zpja5emrl5yrxetamt29swqyqmmt32y","nostr:npub1a3jz7w9laar2k77dkkh2rhxunr9zpja5emrl5yrxetamt29swqyqmmt32y",[862,867],{"title":863,"path":864,"stem":865,"description":866,"children":-1},"What are Web Sockets","\u002Fposts\u002Fwhat-are-web-sockets","posts\u002Fwhat-are-web-sockets","WebSockets are a bi-directional, full duplex communications protocol initiated over HTTP. They are commonly used in modern web applications for streaming data and other asynchronous traffic.",{"title":837,"path":868,"stem":869,"description":870,"children":-1},"\u002Fposts\u002Fwhat-is-an-api","posts\u002Fwhat-is-an-api","API stands for Application Programming Interface. The application can be any software that performs a specific task and the interface is a point where two applications communicate. One application acts as a client and the other acts as a server.",{"id":872,"extension":873,"items":874,"meta":915,"stem":916,"__hash__":917},"navigation\u002Fnavigation.yaml","yaml",[875,888,901,909],{"label":876,"children":877},"products",[878,883],{"label":879,"icon":880,"description":881,"to":882},"Diogel","material-symbols:preview","Keep your Nostr identity in your hands, in your browser, on your phone or on your own server.","\u002Fproducts\u002Fdiogel",{"label":884,"icon":885,"description":886,"to":887},"Nostrfi","i-lucide-radio-tower","Nostr relay, storage and backend-service infrastructure for builders and operators.","\u002Fproducts\u002Fnostrfi",{"label":889,"children":890},"services",[891,896],{"label":892,"description":893,"icon":894,"to":895},"Nostr product development","Focused engineering support for teams building Nostr-native products, tools and protocol-aware user experiences.","game-icons:ostrich","\u002Fservices\u002Fnostr-product-development",{"label":897,"description":898,"icon":899,"to":900},"Bitcoin product development","Engineering for Bitcoin payments, wallet-connected flows and products where users hold their own keys.","bx:bxl-bitcoin","\u002Fservices\u002Fbitcoin-product-development",{"label":902,"children":903},"company",[904],{"label":905,"icon":906,"description":907,"to":908},"About","i-lucide-file-text","What we believe, what we build and how we work.","\u002Fcompany\u002Fabout",{"label":784,"children":910},[911],{"label":912,"icon":906,"description":913,"to":914},"Blog","Practical Bitcoin, Nostr and product engineering guides.","https:\u002F\u002Fthreenine.blog",{},"navigation","n-Xc9COCwoCHJiMCeBNLauHtuhxcGol-wu9S2og3Rqs",{"id":919,"title":853,"avatar":855,"body":920,"description":924,"extension":834,"meta":939,"name":853,"navigation":840,"path":940,"role":941,"sameAs":942,"seo":943,"stem":944,"summary":945,"to":854,"username":7,"__hash__":946},"authors\u002Fauthors\u002FGary Woodfine.md",{"type":9,"value":921,"toc":937},[922,925,928,931,934],[12,923,924],{},"Polyglot software engineer with extensive experience in software engineering, with a passion to build great scalable software to solve complex business problems. A track record in developing high-performance backend systems, optimizing architecture, and ensuring continuous availability of critical APIs.",[12,926,927],{},"I'm an independent software developer, vendor, architect, consultant, blogger, Bitcoin & Nostr Enthusiast. I've provided software development expertise and helped augment software development skills and teams for a number of startups, product companies, corporate IT shops, and consulting firms.",[12,929,930],{},"I started out in the software world back in 1995, building websites with HoTMetaL Pro & ASP and moved on to building web apps with .NET when it released in Beta in 2001, since then, I've shipped systems in just about every industry.",[12,932,933],{},"Along my journey, I have also shipped various platforms & products in a number of other programming languages or software development frameworks that have had their moments in the sun, but somehow I have always made way back to C# & .Net.",[12,935,936],{},"Over the years, I've strived to improve how I and my teams deliver value to the clients, customers, and end-users. That has led me down the path of exploring Agile, Domain-Driven Design, REST, messaging, distributed systems, and anything else I thought could help.",{"title":252,"searchDepth":330,"depth":330,"links":938},[],{},"\u002Fauthors\u002Fgary-woodfine","Managing Director",[857,858,859,860],{"title":853,"description":924},"authors\u002FGary Woodfine","independent software developer, vendor, architect, consultant, blogger, Bitcoin & Nostr Enthusiast. I've provided software development expertise and helped augment software development skills and teams for a number of startups, product companies, corporate IT shops, and consulting firms.","30ZWJ-6T2g8S0kLLgUhZWA7_QFUOpa5CElif7tAhsLo",{"title":853,"name":853,"role":941,"summary":945,"avatar":855,"username":7,"to":854},[949,961,972,979,986,993,1004,1013,1019,1026,1032,1039,1049,1058,1064,1070,1075,1080,1089,1095,1101,1107,1111,1116,1121,1126,1131,1136,1142,1147,1153,1162,1168,1173,1181,1186,1190,1195,1200,1204,1209,1211,1214],{"path":950,"title":951,"date":952,"tags":953,"category":954,"featureImage":959},"\u002Fposts\u002Fwhat-is-a-nostr-client","What is a Nostr client?","2026-10-26",[954,955,956,957,958],"nostr","nostr-client","privacy","keys","getting-started",{"url":960,"title":951},"v1690313893\u002Fnostr-logo_hwrql1",{"path":962,"title":963,"date":964,"tags":965,"category":954,"featureImage":970},"\u002Fposts\u002Fhow-to-choose-nostr-relays","How to Choose Nostr Relays","2026-04-11",[954,966,956,967,968,969],"relay","security","nostr-relays","censorship-resistance",{"url":960,"title":971},"How to choose nostr relays",{"path":973,"title":974,"date":964,"tags":975,"category":954,"featureImage":978},"\u002Fposts\u002Fnostr-relays-privacy-and-security","Nostr Relays, Privacy, and Security",[954,966,956,967,976,977],"key-management","nostr-relay",{"url":960,"title":974},{"path":980,"title":981,"date":964,"tags":982,"category":954,"featureImage":984},"\u002Fposts\u002Fwhat-is-a-nostr-relay","What is a Nostr Relay?",[954,966,956,969,983,977],"decentralization",{"url":960,"title":985}," What is a Nostr Relay?",{"path":987,"title":988,"date":989,"tags":990,"category":954,"featureImage":992},"\u002Fposts\u002Fwhy-nostr-keys-better-privacy","Why Nostr keys and identity are better for privacy","2026-04-06",[954,956,991,967],"identity",{"url":960,"title":988},{"path":994,"title":995,"date":996,"tags":997,"category":954,"featureImage":1003},"\u002Fposts\u002Fbest-nostr-browser-extensions-2026","Best Nostr Browser Extensions (2026): Complete Comparison","2026-03-24",[954,998,999,967,1000,1001,1002],"browser-extension","nip-07","comparison","porwr","diogel",{"url":960,"title":995},{"path":1005,"title":1006,"date":996,"tags":1007,"category":954,"featureImage":1010},"\u002Fposts\u002Fhow-to-get-started-with-porwr","Getting Started with Nostr: Porwr Setup Guide (2026)",[1008,956,954,1001,1002,1009,999,998],"social","cryptography",{"url":1011,"title":1012},"v1690313893\u002Fblog\u002Fdiogel-product-header_x3az6t","Porwr Browser Extension",{"path":1014,"title":1015,"date":1016,"tags":1017,"category":954,"featureImage":1018},"\u002Fposts\u002Fhow-to-manage-keys-for-nostr","How to manage keys for Nostr","2025-12-15",[954,957,956,967],{"url":960,"title":1015},{"path":1020,"title":1021,"date":1016,"tags":1022,"category":954,"featureImage":1025},"\u002Fposts\u002Fhow-to-self-host-your-nip-05-identity","How to self-host your NIP-05 identity",[954,1023,956,1024],"nip-05","self-hosting",{"url":960,"title":1021},{"path":1027,"title":1028,"date":1029,"tags":6,"category":956,"featureImage":1030},"\u002Fposts\u002Fwhy-privacy-is-a-fundamental-human-right","Why privacy is a fundamental human right","2025-12-09",{"url":1031,"title":1028},"v1690313893\u002Fprivacy-header_exiblo",{"path":1033,"title":1034,"date":1035,"tags":6,"category":1036,"featureImage":1037},"\u002Fposts\u002Fhow-government-monetary-policy-erodes-the-value-of-money","How government monetary policy erodes the value of money","2025-12-01","bitcoin",{"url":1038,"title":1034},"v1719908027\u002Fbitcoin_szcm1m",{"path":1040,"title":1041,"date":1042,"tags":1043,"category":1036,"featureImage":1047},"\u002Fposts\u002Fbitaxe-touch-genesis-batch","Bitaxe Touch Genesis Batch","2025-07-23",[1044,1045,1046],"bitaxe","mining","solo",{"url":1048,"title":1041},"v1690313878\u002Fbitaxe-touch_c6qrjd",{"path":1050,"title":1051,"date":1052,"tags":1053,"category":1036,"featureImage":1057},"\u002Fposts\u002Fbitcoin-is-not-a-ponzi-scheme","Bitcoin is not a Ponzi Scheme","2025-07-22",[1054,1055,1056],"ponzi","economics","investment",{"url":1038,"title":1051},{"path":1059,"title":1060,"date":1052,"tags":1061,"category":1036,"featureImage":1063},"\u002Fposts\u002Fgetting-started-with-public-pool-mining","Getting started with Public Pool Mining",[1045,1046,1062],"lottery",{"url":1038,"title":1060},{"path":1065,"title":1066,"date":1067,"tags":1068,"category":1036,"featureImage":1069},"\u002Fposts\u002Fgetting-started-with-solo-mining","Getting started with solo mining","2025-07-19",[1044,1045,1046,1062],{"url":1038,"title":1066},{"path":1071,"title":1072,"date":1067,"tags":1073,"category":1036,"featureImage":1074},"\u002Fposts\u002Fwhat-is-bitcoin-mining","What is Bitcoin mining",[1045,1036],{"url":1038,"title":1072},{"path":1076,"title":1077,"date":1067,"tags":1078,"category":1036,"featureImage":1079},"\u002Fposts\u002Fwhat-is-solo-mining","What is solo mining",[1046],{"url":1038,"title":1077},{"path":1081,"title":1082,"date":1083,"tags":1084,"category":1036,"featureImage":1087},"\u002Fposts\u002Fhow-to-run-a-bitcoin-node","How to run a Bitcoin Node with Umbrel Home","2025-07-14",[1085,1086],"node","umbrel",{"url":1038,"title":1088},"How to run a Bitcoin node",{"path":1090,"title":1091,"date":1092,"tags":1093,"category":954,"featureImage":1094},"\u002Fposts\u002Fhow-to-get-started-with-nostr","How to get started with Nostr","2024-10-09",[954,958,956,957],{"url":960,"title":1091},{"path":1096,"title":1097,"date":1098,"tags":6,"category":831,"featureImage":1099},"\u002Fposts\u002Fhow-to-use-layouts-and-pages-in-nuxt","How to use layouts and pages in Nuxt","2024-10-08",{"url":1100,"title":1097},"v1690313878\u002Fnuxt-header_tbc9cp",{"path":1102,"title":1103,"date":1104,"tags":6,"category":831,"featureImage":1105},"\u002Fposts\u002Fhow-to-add-tailwindcss-to-nuxt","How to add tailwindcss to nuxt","2024-10-07",{"url":1100,"title":1106},"Getting started with Nuxt",{"path":1108,"title":1106,"date":1109,"tags":6,"category":831,"featureImage":1110},"\u002Fposts\u002Fgetting-started-with-nuxt","2024-10-06",{"url":1100,"title":1106},{"path":1112,"title":1113,"date":1109,"tags":6,"category":831,"featureImage":1114},"\u002Fposts\u002Fhow-to-store-terraform_state-in-digital-ocean-space","How to store Terraform state in DigitalOcean Spaces",{"url":1115,"title":1113},"v1690313893\u002Fterraform-header_ixmkgg",{"path":1117,"title":1118,"date":1119,"tags":6,"category":831,"featureImage":1120},"\u002Fposts\u002Fhow-to-use-terraform-with-digitalocean","How to use Terraform with DigitalOcean","2024-10-05",{"url":1115,"title":1118},{"path":1122,"title":1123,"date":1124,"tags":6,"category":956,"featureImage":1125},"\u002Fposts\u002Fhow-to-add-fathom-analytics-to-nuxt","How to add Fathom Analytics to Nuxt","2024-07-01",{"url":1100,"title":1123},{"path":1127,"title":1128,"date":1124,"tags":6,"category":956,"featureImage":1129},"\u002Fposts\u002Fimportance-of-privacy-in-web-analytics","The Importance of Privacy in Web Analytics",{"url":1130,"title":1128},"v1690313893\u002Fanalytics_nlew9f",{"path":1132,"title":1133,"date":1124,"tags":1134,"category":954,"featureImage":1135},"\u002Fposts\u002Fwhat-is-a-nip-07-signer","What is a NIP-07 signer?",[954,999,998,967],{"url":960,"title":1133},{"path":1137,"title":1138,"date":1124,"tags":1139,"category":954,"featureImage":1141},"\u002Fposts\u002Fwhat-is-nostr","What is Nostr?",[954,1140,956,983],"relays",{"url":960,"title":1138},{"path":1143,"title":1144,"date":1124,"tags":6,"category":956,"featureImage":1145},"\u002Fposts\u002Fwhy-choose-privacy-focused-analytics","Why choose privacy focused Analytics",{"url":1146,"title":1144},"v1690313893\u002Fblog\u002Ffathom-header_y7s0x2",{"path":1148,"title":1149,"date":1150,"tags":6,"category":831,"featureImage":1151},"\u002Fposts\u002Fwhat-is-api-integration","What is API Integration?","2024-06-04",{"url":836,"title":1152},"What is API integration?",{"path":1154,"title":1155,"date":1156,"tags":1157,"category":1036,"featureImage":1159},"\u002Fposts\u002Fhow-blockchain-uses-cryptography","How Blockchain uses Cryptography","2024-05-18",[1158,1009],"blockchain",{"url":1160,"title":1161},"v1690313893\u002Fblockchain_tfrcrd","What is blockchain?",{"path":1163,"title":1164,"date":1165,"tags":6,"category":831,"featureImage":1166},"\u002Fposts\u002Fhow-to-create-a-websocket-server-in-dotnet","How to create a WebSocket server in dotnet","2024-05-15",{"url":1167,"title":1164},"v1719908486\u002Fwebsockets_pjqtld",{"path":1169,"title":1170,"date":1165,"tags":1171,"category":1036,"featureImage":1172},"\u002Fposts\u002Fwhat-is-blockchain","What is Blockchain",[1158,1036],{"url":1160,"title":1161},{"path":1174,"title":1175,"date":1176,"tags":1177,"category":1036,"featureImage":1179},"\u002Fposts\u002Fintroduction-to-public-and-private-key-cryptography","Public Key Cryptography Explained: A Beginner's Guide","2024-05-12",[1178,1036,954],"encryption",{"url":1160,"title":1180},"Introduction to public and private key cryptography",{"path":1182,"title":1183,"date":1176,"tags":1184,"category":1036,"featureImage":1185},"\u002Fposts\u002Fwhat-is-bitcoin","What is Bitcoin?",[1158,1036],{"url":1038,"title":1183},{"path":864,"title":863,"date":1187,"tags":6,"category":831,"featureImage":1188},"2023-09-06",{"url":1167,"title":1189},"What are Websockets",{"path":1191,"title":1192,"date":1193,"tags":6,"category":831,"featureImage":1194},"\u002Fposts\u002Fwhat-is-api-first","What is API First?","2023-07-13",{"url":836,"title":1192},{"path":1196,"title":1197,"date":1198,"tags":6,"category":831,"featureImage":1199},"\u002Fposts\u002Fapi-gateway-pattern","API Gateway Pattern","2023-06-10",{"url":836,"title":1197},{"path":1201,"title":1202,"date":1198,"tags":6,"category":831,"featureImage":1203},"\u002Fposts\u002Fbackend-for-frontend-design-pattern","Backend for Frontend Design Pattern",{"url":836,"title":1202},{"path":1205,"title":1206,"date":832,"tags":6,"category":831,"featureImage":1207},"\u002Fposts\u002Fguide-api-development","An introductory guide to API Development",{"url":836,"title":1208},"API Development",{"path":841,"title":5,"date":832,"tags":6,"category":831,"featureImage":1210},{"url":836,"title":837},{"path":868,"title":837,"date":1212,"tags":6,"category":831,"featureImage":1213},"2023-06-01",{"url":836,"title":837},{"path":1215,"title":1216,"date":1212,"tags":6,"category":831,"featureImage":1217},"\u002Fposts\u002Fwhat-is-api-development","What is API Development ?",{"url":836,"title":1218},"What is API development?",[1220,1221],{"label":892,"description":893,"icon":894,"to":895},{"label":897,"description":898,"icon":899,"to":900},[1223,1224],{"label":879,"icon":880,"description":881,"to":882},{"label":884,"icon":885,"description":886,"to":887},[1226],{"label":905,"icon":906,"description":907,"to":908},[1228,1231,1234,1237,1240],{"path":1229,"title":1230},"\u002Flegals\u002Fcookie-policy","Cookie Policy",{"path":1232,"title":1233},"\u002Flegals\u002Fcopyright","Copyright",{"path":1235,"title":1236},"\u002Flegals\u002Fcustomer-support","Customer Support",{"path":1238,"title":1239},"\u002Flegals\u002Fprivacy-policy","Privacy Policy",{"path":1241,"title":1242},"\u002Flegals\u002Fterms-of-service","Terms of Service",1793132669449]