Árvore de páginas

Você está vendo a versão antiga da página. Ver a versão atual.

Comparar com o atual Ver Histórico da Página

« Anterior Versão 2 Próxima »

A utilização do recurso de @annotations na linguagem TL++ possibilitou a simplificação da escrita para o desenvolvimento de API´s REST, mas ainda é possível desenvolver aplicações sem utilização deste recurso no modo tradicional, trataremos disto nesta documentação.

Inicialização de um serviço REST

Para poder utilizar aplicações REST sem o uso das @annotations, obrigatoriamente é necessário criar um serviço Http por meio de uma função fazendo uso de um objeto JSon. Veremos no exemplo abaixo como fazer isto:

#include "tlpp-core.th"

User Function fInitService()

 Local oVdrCtrl := VdrCtrl():New()
 Local cAppPath := "/examples"
 Local nResult := -1
 Local jConfig

 //Definição das configurações do HttpServer
 jConfig['HTTPSERVER']                             := JsonObject():New()
 jConfig['HTTPSERVER']['Enable']                   := .T.
 jConfig['HTTPSERVER']['Log']                     := .F.
 jConfig['HTTPSERVER']['Charset']                 := "ISO-8859-1"
 jConfig['HTTPSERVER']['Servers']                 := {"INIT_HTTP_REST"}
 
 jConfig['INIT_HTTP_REST']                         := JsonObject():New()
 jConfig['INIT_HTTP_REST']['Port']                 := "9995"
 jConfig['INIT_HTTP_REST']['HostName']             := "TLPP_REST_SERVER"
 jConfig['INIT_HTTP_REST']['ContentTypes']         := "ContentTypes"
 jConfig['INIT_HTTP_REST']['Locations']           := {"HTTP_ROOT_01"}

 jConfig['HTTP_ROOT_01']                           := JsonObject():new()
 jConfig['HTTP_ROOT_01']['Path']                   := cAppPath
 jConfig['HTTP_ROOT_01']['RootPath']               := "C:\tlppCore\bin\root\web"
 jConfig['HTTP_ROOT_01']['DefaultPage']           := {"index.html"}
 jConfig['HTTP_ROOT_01']['ThreadPool']             := "INIT_THREAD_POOL_01"

 jConfig['INIT_THREAD_POOL_01']                   := JsonObject():new()
 jConfig['INIT_THREAD_POOL_01']['MinThreads']     := 1
 jConfig['INIT_THREAD_POOL_01']['MaxThreads']     := 4
 jConfig['INIT_THREAD_POOL_01']['MinFreeThreads'] := 1
 jConfig['INIT_THREAD_POOL_01']['GrowthFactor']   := 1
 jConfig['INIT_THREAD_POOL_01']['InactiveTimeout'] := 30000
 jConfig['INIT_THREAD_POOL_01']['AcceptTimeout']   := 10000
 
 jConfig['INIT_ContentTypes']                     := JsonObject():new()
 jConfig['INIT_ContentTypes']['htm']               := "text/html"
 jConfig['INIT_ContentTypes']['html']             := "text/html"
 jConfig['INIT_ContentTypes']['stm']               := "text/html"
 jConfig['INIT_ContentTypes']['tsp']               := "text/html"
 jConfig['INIT_ContentTypes']['js']               := "text/javascript"
 jConfig['INIT_ContentTypes']['json']             := "text/plain;charset=ISO-8859-1"
 jConfig['INIT_ContentTypes']['*']                 := "application/octet-stream"

 /* -----------------------------------------------------------
 Aqui é feita a chamada para a função responsável por criar o
 vinculo entre URN´s e as aplicações
 ----------------------------------------------------------- */
 jConfig['INIT_HTTP_REST']['LoadURNs']             := JsonObject():new()
 if !( sLoadURNs(@jConfig['INIT_HTTP_REST']['LoadURNs']) )
   return Nil
 endif
 /*------------------------------------------------------------*/

 nResult := oVdrCtrl:Start(jConfig)
 if ( ValType(nResult) == 'N' .AND. nResult == 0 )
   conout("### Servidor HTTP inicializado com sucesso!")
 else
   conout("### Erro ao iniciar HTTP Server - retorno [" + cValToChar(nResult) + "] - " + cValToChar(oVdrCtrl:getControlErrCode()) + " - " + oVdrCtrl:getControlErrDesc() )
 endif

return nResult


OBS.: Caso já exista algum serviço REST sendo criado por meio de função utilizando-se um JSon, basta incluir a chamada da static sLoadUrn como será visto no item posterior.


Vinculando a URN à API

Como não está sendo utilizado o recurso das @annotations para poder desenvolver API´s REST, é preciso utilizar outra forma para efetuar o vínculo com a URN, isto é feito via função. A mesma é chamada do ponto destacado na função do item anterior, no exemplo citado está sendo feita a chamada para uma função do tipo Static, mas, nada impede que ela seja do tipo User, desde que respeitando o tipo de retorno e as regras de implementações que serão vistas no exemplo a seguir:

//Static Function responsável por criar o nó contendo o vínculo entre as URN´s e as API´s(funções) no objeto jSon que foi recebido como parametro e será utilizado no serviço REST que será executado a partir das definições do mesmo.

Static Function sLoadURNs(jEndpoints)

 Local cDelPath   := "/documentation/noannotation/delete"
 Local cGetPath   := "/documentation/noannotation/get"
 Local cPatchPath := "/documentation/noannotation/patch"
 Local cPostPath   := "/documentation/noannotation/post"
 Local cPutPath   := "/documentation/noannotation/put"

 if(ValType(jEndpoints) == 'U' .Or. ValType(jEndpoints) != 'J')
   jEndpoints := jsonObject():New()
 endIf

 jEndpoints[cGetPath] := JsonObject():new()
 
 jEndpoints[cGetPath]['GET']                   := JsonObject():new()
 jEndpoints[cGetPath]['GET']['ClassName']     := ""
 jEndpoints[cGetPath]['GET']['Function']       := "U_getExampleNoAnnotation"
 jEndpoints[cGetPath]['GET']['EndPoint']       :={"documentation", "noannotation", "get"}

 jEndpoints[cDelPath]['DELETE']               := JsonObject():new()
 jEndpoints[cDelPath]['DELETE']['ClassName']   := ""
 jEndpoints[cDelPath]['DELETE']['Function']   := "U_deleteExampleNoAnnotation"
 jEndpoints[cDelPath]['DELETE']['EndPoint']   :={"documentation", "noannotation", "delete"}

 jEndpoints[cPatchPath]['PATCH']               := JsonObject():new()
 jEndpoints[cPatchPath]['PATCH']['ClassName'] := ""
 jEndpoints[cPatchPath]['PATCH']['Function']   := "U_patchExampleNoAnnotation"
 jEndpoints[cPatchPath]['PATCH']['EndPoint']   :={"documentation", "noannotation", "patch"}

 jEndpoints[cPostPath]['POST']                 := JsonObject():new()
 jEndpoints[cPostPath]['POST']['ClassName']   := ""
 jEndpoints[cPostPath]['POST']['Function']     := "U_postExampleNoAnnotation"
 jEndpoints[cPostPath]['POST']['EndPoint']     :={"documentation", "noannotation", "post"}

 jEndpoints[cPutPath]['PUT']                 := JsonObject():new()
 jEndpoints[cPutPath]['PUT']['ClassName']     := ""
 jEndpoints[cPutPath]['PUT']['Function']     := "U_putExampleNoAnnotation"
 jEndpoints[cPutPath]['PUT']['EndPoint']     :={"documentation", "noannotation", "put"}
 
Return .T.


OBSERVAÇÃO

As funções, os endpoints e as demais configurações utilizadas nos exemplos vistos aqui, devem ser criados conforme as regras e as necessidades de utilização de cada ambiente e desenvolvedor.

  • Sem rótulos