Програмиране с Java API, Част 1: OpenAPI и Swagger

Докато си пиете кафето, разработката на приложения на Java се промени - отново .

В свят, задвижван от бързи промени и иновации, иронично е, че API се завръщат. Подобно на кодиращия еквивалент на метрото на Ню Йорк в ерата на автономните автомобили, API са стари технологии - древни, но задължителни. Интересното е как тази невидима, ежедневна ИТ архитектура се преосмисля и използва в съвременните технологични тенденции.

Докато API са навсякъде, те станаха особено забележителни в отдалеченото си въплъщение като RESTful услуги, които са гръбнакът на облачните внедрения. Облачните услуги са публични API , които се характеризират с публични крайни точки и публикувани структури. Облачните приложения също са насочени към микроуслуги , които са независими, но свързани внедрявания. Всички тези фактори увеличават популярността на API.

В този урок от две части ще научите как да поставите Java API в основата на процеса на проектиране и разработка, от концепция до кодиране. Част 1 започва с общ преглед и ви представя OpenAPI, известен също като Swagger. В част 2 ще научите как да използвате дефинициите на API на Swagger за разработване на Spring Web MVC приложение с фронтален ъгъл 2.

Какво е Java API?

Приложните програмни интерфейси са толкова често срещано явление при разработването на софтуер, че понякога се приема, че програмистите просто знаят какви са. Вместо да разчитаме на осмоза, нека отделим минута, за да разопаковаме какво имаме предвид, когато говорим за API.

Като цяло можем да кажем, че API-тата задават и управляват границите между системите.

Първо, API означава „интерфейс за програмиране на приложения“. Ролята на API е да определя как взаимодействат софтуерните компоненти. Ако сте запознати с обектно-ориентираното програмиране, вие знаете API-та в тяхното въплъщение като интерфейси и класове, използвани за получаване на достъп до основните характеристики на езика, или като публично лице на библиотеки на трети страни и възможности на ОС.

Като цяло можем да кажем, че API-тата задават и управляват границите между системите, както се вижда на Фигура 1.

Матю Тайсън

И така, къде ни оставя разработката, управлявана от API?

Java API за облачни изчисления, микроуслуги и REST

Програмирането с API излиза на преден план със съвременния уеб API: мрежово изложен API (NEA) , където границата между системите е „по жицата“. Тези граници вече са от основно значение за уеб приложенията, които са общата точка за контакт между клиенти от предния край и сървъри от заден край. Облачната революция експоненциално увеличи значението на Java API.

Всяка дейност по програмиране, която изисква консумация на облачни услуги (които са основно публични API) и деконструиране на системи в по-малки, независими, но свързани внедрявания (известни също като микросервизи), разчита силно на API. Изложените в мрежа API са просто по-универсални, по-лесно получени и по-лесно модифицирани и разширени от традиционните API. Настоящата архитектурна тенденция е да се възползват от тези характеристики.

Микроуслугите и публичните приложни програмни интерфейси (API) са създадени от корените на ориентираната към услуги архитектура (SOA) и софтуера като услуга (SaaS). Въпреки че SOA е тенденция от много години, широкото приемане е възпрепятствано от сложността и режийните разходи на SOA. Индустрията се спря на RESTful API като де факто стандарт, предоставящ достатъчно достатъчно структура и конвенция с повече реална гъвкавост. С REST като фон можем да създадем официални дефиниции на API, които запазват човешката четливост. Разработчиците създават инструменти около тези определения.

Като цяло REST е конвенция за картографиране на ресурси към HTTP пътища и свързаните с тях действия. Вероятно сте ги виждали като HTTP GET и POST методи. Ключовото е да се използва самият HTTP като стандарт и да се сложат конвенционални съпоставяния отгоре на това за предсказуемост.

Използване на Java API в дизайна

Можете да видите важността на API, но как бихте ги използвали във ваша полза?

Използването на дефиниции на Java API за стимулиране на процеса на проектиране и разработване е ефективен начин да структурирате вашето мислене за ИТ системи. Използвайки дефинициите на Java API от самото начало на жизнения цикъл на разработката на софтуер (събиране на концепция и изисквания), вие ще създадете ценен технически артефакт, който е полезен до разгръщането, както и за текуща поддръжка.

Нека да разгледаме как дефинициите на Java API свързват концептуалния етап и етапите на изпълнение на разработката.

Описателни срещу предписани API

Полезно е да правите разлика между описателните и предписаните API. А описателен API описва начина, кодът всъщност функции, докато предписания API описва как кодът трябва да функционира.

И двата стила са полезни и двата са значително подобрени чрез използване на структуриран стандартен формат за дефиниране на API. Като правило, използването на API за задвижване на създаването на код е предписана употреба, докато използването на кода за извеждане на дефиницията на Java API е описателна употреба.

Събиране на изисквания с Java API

Що се отнася до концептуалния за изпълнение спектър, събирането на изисквания е далеч откъм концепцията. Но дори в концептуалния етап на разработчика на приложения можем да започнем да мислим по отношение на API.

Кажете, че вашата система в дизайна се занимава с планински велосипеди - конструкция, части и т.н. Като обектно-ориентиран разработчик ще започнете, като говорите със заинтересованите страни за изискванията. Доста бързо след това бихте си помислили за абстрактен BikePartклас.

След това ще помислите чрез уеб приложението, което ще управлява различните обекти на части за велосипеди. Скоро ще стигнете до общи изисквания за управление на тези части на велосипеда. Ето моментна снимка на фазата на изискванията на документацията за приложение за велосипедни части:

  • Приложението трябва да може да създаде тип велосипедна част (превключвател на скоростите, спирачка и т.н.).
  • Оторизиран потребител трябва да може да изброява, създава и активира даден тип част.
  • Неоторизиран потребител трябва да може да изброява активни типове части и да преглежда списъци на отделни екземпляри от частния тип в системата.

Вече можете да видите очертанията на услугите, които се оформят. Имайки предвид евентуалните API, можете да започнете да очертавате тези услуги. Като пример, ето частичен списък на RESTful CRUD услугите за типове части за велосипеди:

  • Създайте тип част за велосипед: PUT /part-type/
  • Актуализиране на типа част на велосипеда: POST /part-type/
  • Избройте типовете части: GET /part-type/
  • Вземете подробности за типа част: GET /part-type/:id

Забележете как CRUD услугите започват да намекват за формата на различни граници на услуги. Ако изграждате в стил микроуслуги, вече можете да видите три микроуслуги, излизащи от дизайна:

  • Услуга за велосипедни части
  • Услуга от тип тип велосипед
  • Услуга за удостоверяване / оторизация

Because I think of APIs as boundaries of related entities, I consider the microservices from this list to be API surfaces. Together, they offer a big-picture view of the application architecture. Details of the services themselves are also described in a fashion that you will use for the technical specification, which is the next phase of the software development lifecycle.

Technical specification with Java APIs

If you've included the API focus as part of requirements gathering, then you already have a good framework for technical specification. The next stage is selecting the technology stack you will use to implement the specification.

With so much focus on building RESTful APIs, developers have an embarrassment of riches when it comes to implementation. Regardless of the stack you choose, fleshing out the API even further at this stage will increase your understanding of the app's architectural needs. Options might include a VM (virtual machine) to host the application, a database capable of managing the volume and type of data you're serving, and a cloud platform in the case of IaaS or PaaS deployment.

You can use the API to drive "downward" toward schemas (or document structures n NoSQL), or "upward" toward UI elements. As you develop the API specification, you will likely notice an interplay between these concerns. This is all good and part of the process. The API becomes a central, living place to capture these changes.

Another concern to keep in mind is which public APIs your system will expose. Give extra thought and care to these. Along with assisting in the development effort, public APIs serve as the published contract that external systems use to interface with yours.

Public cloud APIs

In general, APIs define the contract of a software system, providing a known and stable interface against which to program other systems. Specifically, a public cloud API is a public contract with other organizations and programmers building systems. Examples are the GitHub and Facebook APIs.

Documenting the Java API

At this stage, you will want to start capturing your APIs in formal syntax. I've listed a few prominent API standards in Table 1.

Comparing API formats

 
Name Summary Stars on GitHub URL
OpenAPI JSON and YML Supported API Standard descended from the Swagger project, includes variety of tools in the Swagger ecosystem. ~6,500 //github.com/OAI/OpenAPI-Specification
RAML YML based spec supported mainly by MuleSoft ~3,000 //github.com/raml-org/raml-spec
API BluePrint An API design language using MarkDown-like syntax ~5,500 //github.com/apiaryio/api-blueprint/

Virtually any format you choose for documenting your API should be okay. Just look for a format that is structured, has a formal spec and good tooling around it, and looks like it will be actively maintained long term. Both RAML and OpenAPI fit that bill. Another neat project is API Blueprint, which uses markdown syntax. For examples in this article we're going to use OpenAPI and Swagger.

OpenAPI and Swagger

OpenAPI is a JSON format for describing REST-based APIs. Swagger started as OpenAPI, but has evolved into a set of tools around the OpenAPI format. The two technologies complement each other well.

Introducing OpenAPI

OpenAPI is currently the most common choice for creating RESTful definitions. A compelling alternative is RAML (RESTful API Markup Language), which is based on YAML. Personally, I've found the tooling in Swagger (especially the visual designer) more polished and error-free than in RAML.

OpenAPI uses JSON syntax, which is familiar to most developers. If you'd rather not strain your eyes parsing JSON, there are UIs to make working with it easier. Part 2 introduces UIs for RESTful definitions.

Listing 1 is a sample of OpenAPI's JSON syntax.

Listing 1. OpenAPI definition for a simple BikePart

 "paths": { "/part-type": { "get": { "description": "Gets all the part-types available in the system", "operationId": "getPartTypes", "produces": [ "application/json" ], "responses": { "200": { "description": "Gets the BikeParts", "schema": { "type": "array", "items": { "$ref": "#/definitions/BikePart" } } } } } } } 

This definition is so concise it is practically Spartan, which is fine for now. There's plenty of room to increase the detail and complexity of the API definition going forward. I'll show you a more detailed iteration of this definition shortly.

Coding from the Java API

Requirements gathering is done and the basic app has been spec'd out, which means you're ready for the fun part---coding! Having a formal Java API definition gives you some distinct advantages. For one thing, you know what endpoints the back-end and front-end developers need to create and code against, respectively. Even if you are a team of one, you'll quickly see the value of an API-driven approach when you begin coding.

Докато изграждате приложението, ще видите и стойността на използването на API за улавяне на преговори напред-назад между разработката и бизнеса. Използването на API инструменти ще ускори както прилагането, така и документирането на промените в кода.

По-подробните спецификации и действителното кодиране може да изискват по-големи подробности от краткото определение в Листинг 1. Освен това по-големите и по-сложни системи могат да заслужават възможности, които ще се мащабират, като препратки към документи. Листинг 2 показва по-подробен пример за BikePart API.

Листинг 2. Добавяне на детайли към дефиницията на BikePart API

 "paths": { "/part-type": { "get": { "description": "Gets all the part-types available in the system", "operationId": "getPartTypes", "produces": [ "application/json" ], "parameters": [ { "name": "limit", "in": "query", "description": "maximum number of results to return", "required": false, "type": "integer", "format": "int32" } ], "responses": { "200": { "description": "part-type listing", "schema": { "type": "array", "items": { "$ref": "#/definitions/PartType" } } }, "default": { "description": "unexpected error", "schema": { "$ref": "#/definitions/Error" } } } }