-
Notifications
You must be signed in to change notification settings - Fork 25
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[#174877080] Upgrade to italia-utils 5.x #711
Changes from 3 commits
0027732
7f8a935
b801cf8
d97ea72
bd570ea
614692c
17de3fe
5e081c3
704b5e3
260e6b4
1465d94
d06ce61
b2e7987
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,239 +1,33 @@ | ||
import { | ||
ApiHeaderJson, | ||
composeHeaderProducers, | ||
composeResponseDecoders, | ||
constantResponseDecoder, | ||
createFetchRequestForApi, | ||
ioResponseDecoder, | ||
ReplaceRequestParams, | ||
RequestHeaderProducer, | ||
RequestParams, | ||
TypeofApiCall | ||
} from "italia-ts-commons/lib/requests"; | ||
import { ProblemJson } from "italia-ts-commons/lib/responses"; | ||
import { Omit } from "italia-ts-commons/lib/types"; | ||
import nodeFetch from "node-fetch"; | ||
|
||
import { | ||
createProfileDefaultDecoder, | ||
CreateProfileT, | ||
getMessageDefaultDecoder, | ||
getMessagesByUserDefaultDecoder, | ||
GetMessagesByUserT, | ||
GetMessageT, | ||
getProfileDefaultDecoder, | ||
GetProfileT, | ||
getServiceDefaultDecoder, | ||
GetServiceT, | ||
getUserDataProcessingDefaultDecoder, | ||
GetUserDataProcessingT, | ||
getVisibleServicesDefaultDecoder, | ||
GetVisibleServicesT, | ||
StartEmailValidationProcessT, | ||
updateProfileDefaultDecoder, | ||
UpdateProfileT, | ||
upsertUserDataProcessingDefaultDecoder, | ||
UpsertUserDataProcessingT | ||
} from "../../generated/io-api/requestTypes"; | ||
import { Client, createClient } from "../../generated/io-api/client"; | ||
|
||
// we want to authenticate against the platform APIs with the APIM header key or | ||
// the Azure Functions header key, so we send both headers | ||
function SubscriptionKeyHeaderProducer<P>( | ||
/* function SubscriptionKeyHeaderProducer<P>( | ||
token: string | ||
): RequestHeaderProducer<P, "X-Functions-Key" | "Ocp-Apim-Subscription-Key"> { | ||
return () => ({ | ||
"Ocp-Apim-Subscription-Key": token, | ||
"X-Functions-Key": token | ||
}); | ||
} | ||
} */ | ||
|
||
export function APIClient( | ||
baseUrl: string, | ||
token: string, | ||
// tslint:disable-next-line:no-any | ||
fetchApi: typeof fetch = (nodeFetch as any) as typeof fetch // TODO: customize fetch with timeout | ||
): { | ||
readonly updateProfile: TypeofApiCall<typeof updateProfileT>; | ||
readonly getMessage: TypeofApiCall<typeof getMessageT>; | ||
readonly getMessages: TypeofApiCall<typeof getMessagesT>; | ||
readonly getProfile: TypeofApiCall<typeof getProfileT>; | ||
readonly createProfile: TypeofApiCall<typeof createProfileT>; | ||
readonly upsertUserDataProcessing: TypeofApiCall< | ||
typeof upsertUserDataProcessingT | ||
>; | ||
readonly emailValidationProcess: TypeofApiCall< | ||
typeof emailValidationProcessT | ||
>; | ||
readonly getService: TypeofApiCall<typeof getServiceT>; | ||
readonly getVisibleServices: TypeofApiCall<typeof getVisibleServicesT>; | ||
readonly getUserDataProcessing: TypeofApiCall<typeof getUserDataProcessingT>; | ||
} { | ||
const options = { | ||
): Client<"SubscriptionKey"> { | ||
return createClient<"SubscriptionKey">({ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this must be x-functions-key (Ocp-Apim-Subscription-Key is unused) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It actually is. The referenced api spec is SubscriptionKey:
type: apiKey
name: X-Functions-Key
in: header Under the hood, the generated client does the following: headers: ({ SubscriptionKey }: { SubscriptionKey: string }) => ({
"X-Functions-Key": `Bearer ${SubscriptionKey}`
}), There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. that's right, not easy to grasp from the code here :-) (maybe we could add a comment?) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done here |
||
basePath: "", | ||
baseUrl, | ||
fetchApi | ||
}; | ||
|
||
const tokenHeaderProducer = SubscriptionKeyHeaderProducer(token); | ||
|
||
// Custom decoder until we fix the problem in the io-utils generator | ||
// https://www.pivotaltracker.com/story/show/169915207 | ||
// tslint:disable-next-line:typedef | ||
function startEmailValidationProcessCustomDecoder() { | ||
return composeResponseDecoders( | ||
composeResponseDecoders( | ||
composeResponseDecoders( | ||
composeResponseDecoders( | ||
constantResponseDecoder<undefined, 202>(202, undefined), | ||
ioResponseDecoder< | ||
400, | ||
typeof ProblemJson["_A"], | ||
typeof ProblemJson["_O"] | ||
>(400, ProblemJson) | ||
), | ||
constantResponseDecoder<undefined, 401>(401, undefined) | ||
), | ||
constantResponseDecoder<undefined, 404>(404, undefined) | ||
), | ||
constantResponseDecoder<undefined, 429>(429, undefined) | ||
); | ||
} | ||
|
||
const getProfileT: ReplaceRequestParams< | ||
GetProfileT, | ||
Omit<RequestParams<GetProfileT>, "SubscriptionKey"> | ||
> = { | ||
headers: tokenHeaderProducer, | ||
method: "get", | ||
query: _ => ({}), | ||
response_decoder: getProfileDefaultDecoder(), | ||
url: params => `/profiles/${params.fiscalCode}` | ||
}; | ||
|
||
const createProfileT: ReplaceRequestParams< | ||
CreateProfileT, | ||
Omit<RequestParams<CreateProfileT>, "SubscriptionKey"> | ||
> = { | ||
body: params => JSON.stringify(params.newProfile), | ||
headers: composeHeaderProducers(tokenHeaderProducer, ApiHeaderJson), | ||
method: "post", | ||
query: _ => ({}), | ||
response_decoder: createProfileDefaultDecoder(), | ||
url: params => `/profiles/${params.fiscalCode}` | ||
}; | ||
|
||
const updateProfileT: ReplaceRequestParams< | ||
UpdateProfileT, | ||
Omit<RequestParams<UpdateProfileT>, "SubscriptionKey"> | ||
> = { | ||
body: params => JSON.stringify(params.profile), | ||
headers: composeHeaderProducers(tokenHeaderProducer, ApiHeaderJson), | ||
method: "put", | ||
query: _ => ({}), | ||
response_decoder: updateProfileDefaultDecoder(), | ||
url: params => `/profiles/${params.fiscalCode}` | ||
}; | ||
|
||
const emailValidationProcessT: ReplaceRequestParams< | ||
StartEmailValidationProcessT, | ||
Omit<RequestParams<StartEmailValidationProcessT>, "SubscriptionKey"> | ||
> = { | ||
body: _ => "{}", | ||
headers: composeHeaderProducers(tokenHeaderProducer, ApiHeaderJson), | ||
method: "post", | ||
query: _ => ({}), | ||
response_decoder: startEmailValidationProcessCustomDecoder(), | ||
url: params => `/email-validation-process/${params.fiscalCode}` | ||
}; | ||
|
||
const getUserDataProcessingT: ReplaceRequestParams< | ||
GetUserDataProcessingT, | ||
Omit<RequestParams<GetUserDataProcessingT>, "SubscriptionKey"> | ||
> = { | ||
headers: tokenHeaderProducer, | ||
method: "get", | ||
query: _ => ({}), | ||
response_decoder: getUserDataProcessingDefaultDecoder(), | ||
url: params => | ||
`/user-data-processing/${params.fiscalCode}/${params.userDataProcessingChoiceParam}` | ||
}; | ||
|
||
const getMessagesT: ReplaceRequestParams< | ||
GetMessagesByUserT, | ||
Omit<RequestParams<GetMessagesByUserT>, "SubscriptionKey"> | ||
> = { | ||
headers: tokenHeaderProducer, | ||
method: "get", | ||
query: _ => ({}), | ||
response_decoder: getMessagesByUserDefaultDecoder(), | ||
url: params => `/messages/${params.fiscalCode}` | ||
}; | ||
|
||
const getMessageT: ReplaceRequestParams< | ||
GetMessageT, | ||
Omit<RequestParams<GetMessageT>, "SubscriptionKey"> | ||
> = { | ||
headers: tokenHeaderProducer, | ||
method: "get", | ||
query: _ => ({}), | ||
response_decoder: getMessageDefaultDecoder(), | ||
url: params => `/messages/${params.fiscalCode}/${params.id}` | ||
}; | ||
|
||
const getVisibleServicesT: ReplaceRequestParams< | ||
GetVisibleServicesT, | ||
Omit<RequestParams<GetVisibleServicesT>, "SubscriptionKey"> | ||
> = { | ||
headers: tokenHeaderProducer, | ||
method: "get", | ||
query: _ => ({}), | ||
response_decoder: getVisibleServicesDefaultDecoder(), | ||
url: () => `/services` | ||
}; | ||
|
||
const getServiceT: ReplaceRequestParams< | ||
GetServiceT, | ||
Omit<RequestParams<GetServiceT>, "SubscriptionKey"> | ||
> = { | ||
headers: tokenHeaderProducer, | ||
method: "get", | ||
query: _ => ({}), | ||
response_decoder: getServiceDefaultDecoder(), | ||
url: params => `/services/${params.service_id}` | ||
}; | ||
|
||
const upsertUserDataProcessingT: ReplaceRequestParams< | ||
UpsertUserDataProcessingT, | ||
Omit<RequestParams<UpsertUserDataProcessingT>, "SubscriptionKey"> | ||
> = { | ||
body: params => JSON.stringify(params.userDataProcessingChoiceRequest), | ||
headers: composeHeaderProducers(tokenHeaderProducer, ApiHeaderJson), | ||
method: "post", | ||
query: _ => ({}), | ||
response_decoder: upsertUserDataProcessingDefaultDecoder(), | ||
url: params => `/user-data-processing/${params.fiscalCode}` | ||
}; | ||
|
||
return { | ||
createProfile: createFetchRequestForApi(createProfileT, options), | ||
emailValidationProcess: createFetchRequestForApi( | ||
emailValidationProcessT, | ||
options | ||
), | ||
getMessage: createFetchRequestForApi(getMessageT, options), | ||
getMessages: createFetchRequestForApi(getMessagesT, options), | ||
getProfile: createFetchRequestForApi(getProfileT, options), | ||
getService: createFetchRequestForApi(getServiceT, options), | ||
getUserDataProcessing: createFetchRequestForApi( | ||
getUserDataProcessingT, | ||
options | ||
), | ||
getVisibleServices: createFetchRequestForApi(getVisibleServicesT, options), | ||
updateProfile: createFetchRequestForApi(updateProfileT, options), | ||
upsertUserDataProcessing: createFetchRequestForApi( | ||
upsertUserDataProcessingT, | ||
options | ||
) | ||
}; | ||
fetchApi, | ||
withDefaults: op => params => | ||
op({ | ||
...params, | ||
SubscriptionKey: token | ||
}) | ||
}); | ||
} | ||
|
||
export type APIClient = typeof APIClient; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gunzip @francescopersico please take a look here:
the former code used to pass
token
to bothX-Functions-Key
andOcp-Apim-Subscription-Key
header. With the latest implementation, only the latter is valued. Which is the correct configuration?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we must update the specs on io-functions-app to take only X-Functions-Key
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pagopa/io-functions-app#106